mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-07-31 21:11:35 +00:00
fix: simple table issues on mobile (#7115)
* fix: header row/column tap areas are too small on mobile * test: header row/column tap areas are too small on mobile * feat: enable auto scroll after inserting column or row * fix: enter after emoji will create a softbreak on mobile * fix: header row/column tap areas are too small on mobile * fix: simple table alignment not work for item that wraps * test: simple table alignment not work for item that wraps
This commit is contained in:
parent
7dedb84504
commit
8f7cb50dd4
@ -2,9 +2,10 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/simple_table/simple_table.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/simple_table/simple_table.dart';
|
||||||
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/simple_table/simple_table_widgets/_simple_table_bottom_sheet_actions.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
|
||||||
@ -244,6 +245,53 @@ void main() {
|
|||||||
expect(table.isHeaderColumnEnabled, isTrue);
|
expect(table.isHeaderColumnEnabled, isTrue);
|
||||||
expect(table.isHeaderRowEnabled, isTrue);
|
expect(table.isHeaderRowEnabled, isTrue);
|
||||||
|
|
||||||
|
// disable header column
|
||||||
|
{
|
||||||
|
// focus on the first cell
|
||||||
|
unawaited(
|
||||||
|
editorState.updateSelectionWithReason(
|
||||||
|
Selection.collapsed(Position(path: firstParagraphPath)),
|
||||||
|
reason: SelectionUpdateReason.uiEvent,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// click the row menu button
|
||||||
|
await tester.clickColumnMenuButton(0);
|
||||||
|
|
||||||
|
final toggleButton = find.descendant(
|
||||||
|
of: find.byType(SimpleTableHeaderActionButton),
|
||||||
|
matching: find.byType(CupertinoSwitch),
|
||||||
|
);
|
||||||
|
await tester.tapButton(toggleButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable header row
|
||||||
|
{
|
||||||
|
// focus on the first cell
|
||||||
|
unawaited(
|
||||||
|
editorState.updateSelectionWithReason(
|
||||||
|
Selection.collapsed(Position(path: firstParagraphPath)),
|
||||||
|
reason: SelectionUpdateReason.uiEvent,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// click the row menu button
|
||||||
|
await tester.clickRowMenuButton(0);
|
||||||
|
|
||||||
|
// enable header column
|
||||||
|
final toggleButton = find.descendant(
|
||||||
|
of: find.byType(SimpleTableHeaderActionButton),
|
||||||
|
matching: find.byType(CupertinoSwitch),
|
||||||
|
);
|
||||||
|
await tester.tapButton(toggleButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the table is updated
|
||||||
|
expect(table.isHeaderColumnEnabled, isFalse);
|
||||||
|
expect(table.isHeaderRowEnabled, isFalse);
|
||||||
|
|
||||||
// set to page width
|
// set to page width
|
||||||
{
|
{
|
||||||
final table = editorState.getNodeAtPath([0])!;
|
final table = editorState.getNodeAtPath([0])!;
|
||||||
|
@ -86,6 +86,9 @@ class SimpleTableContext {
|
|||||||
/// This value is available on mobile only
|
/// This value is available on mobile only
|
||||||
final ValueNotifier<int?> isReorderingHitIndex = ValueNotifier(null);
|
final ValueNotifier<int?> isReorderingHitIndex = ValueNotifier(null);
|
||||||
|
|
||||||
|
/// Scroll controller for the table
|
||||||
|
ScrollController? horizontalScrollController;
|
||||||
|
|
||||||
void _onHoveringOnColumnsAndRowsChanged() {
|
void _onHoveringOnColumnsAndRowsChanged() {
|
||||||
if (!_enableTableDebugLog) {
|
if (!_enableTableDebugLog) {
|
||||||
return;
|
return;
|
||||||
|
@ -117,6 +117,8 @@ extension TableOptionOperation on EditorState {
|
|||||||
required Node tableCellNode,
|
required Node tableCellNode,
|
||||||
required TableAlign align,
|
required TableAlign align,
|
||||||
}) async {
|
}) async {
|
||||||
|
await clearColumnTextAlign(tableCellNode: tableCellNode);
|
||||||
|
|
||||||
final columnIndex = tableCellNode.columnIndex;
|
final columnIndex = tableCellNode.columnIndex;
|
||||||
await _updateTableAttributes(
|
await _updateTableAttributes(
|
||||||
tableCellNode: tableCellNode,
|
tableCellNode: tableCellNode,
|
||||||
@ -144,6 +146,8 @@ extension TableOptionOperation on EditorState {
|
|||||||
required Node tableCellNode,
|
required Node tableCellNode,
|
||||||
required TableAlign align,
|
required TableAlign align,
|
||||||
}) async {
|
}) async {
|
||||||
|
await clearRowTextAlign(tableCellNode: tableCellNode);
|
||||||
|
|
||||||
final rowIndex = tableCellNode.rowIndex;
|
final rowIndex = tableCellNode.rowIndex;
|
||||||
await _updateTableAttributes(
|
await _updateTableAttributes(
|
||||||
tableCellNode: tableCellNode,
|
tableCellNode: tableCellNode,
|
||||||
@ -385,4 +389,67 @@ extension TableOptionOperation on EditorState {
|
|||||||
transaction.updateNode(parentTableNode, attributes);
|
transaction.updateNode(parentTableNode, attributes);
|
||||||
await apply(transaction);
|
await apply(transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clear the text align of the column at the index where the table cell node is located.
|
||||||
|
Future<void> clearColumnTextAlign({
|
||||||
|
required Node tableCellNode,
|
||||||
|
}) async {
|
||||||
|
final parentTableNode = tableCellNode.parentTableNode;
|
||||||
|
if (parentTableNode == null) {
|
||||||
|
Log.warn('parent table node is null');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final columnIndex = tableCellNode.columnIndex;
|
||||||
|
final transaction = this.transaction;
|
||||||
|
for (var i = 0; i < parentTableNode.rowLength; i++) {
|
||||||
|
final cell = parentTableNode.getTableCellNode(
|
||||||
|
rowIndex: i,
|
||||||
|
columnIndex: columnIndex,
|
||||||
|
);
|
||||||
|
if (cell == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (final child in cell.children) {
|
||||||
|
transaction.updateNode(child, {
|
||||||
|
blockComponentAlign: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (transaction.operations.isNotEmpty) {
|
||||||
|
await apply(transaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clear the text align of the row at the index where the table cell node is located.
|
||||||
|
Future<void> clearRowTextAlign({
|
||||||
|
required Node tableCellNode,
|
||||||
|
}) async {
|
||||||
|
final parentTableNode = tableCellNode.parentTableNode;
|
||||||
|
if (parentTableNode == null) {
|
||||||
|
Log.warn('parent table node is null');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final rowIndex = tableCellNode.rowIndex;
|
||||||
|
final transaction = this.transaction;
|
||||||
|
for (var i = 0; i < parentTableNode.columnLength; i++) {
|
||||||
|
final cell = parentTableNode.getTableCellNode(
|
||||||
|
rowIndex: rowIndex,
|
||||||
|
columnIndex: i,
|
||||||
|
);
|
||||||
|
if (cell == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (final child in cell.children) {
|
||||||
|
transaction.updateNode(
|
||||||
|
child,
|
||||||
|
{
|
||||||
|
blockComponentAlign: null,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (transaction.operations.isNotEmpty) {
|
||||||
|
await apply(transaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,16 @@ class _DesktopSimpleTableWidgetState extends State<DesktopSimpleTableWidget> {
|
|||||||
final scrollController = ScrollController();
|
final scrollController = ScrollController();
|
||||||
late final editorState = context.read<EditorState>();
|
late final editorState = context.read<EditorState>();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
simpleTableContext.horizontalScrollController = scrollController;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
simpleTableContext.horizontalScrollController = null;
|
||||||
scrollController.dispose();
|
scrollController.dispose();
|
||||||
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
@ -47,8 +47,16 @@ class _MobileSimpleTableWidgetState extends State<MobileSimpleTableWidget> {
|
|||||||
final scrollController = ScrollController();
|
final scrollController = ScrollController();
|
||||||
late final editorState = context.read<EditorState>();
|
late final editorState = context.read<EditorState>();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
simpleTableContext.horizontalScrollController = scrollController;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
simpleTableContext.horizontalScrollController = null;
|
||||||
scrollController.dispose();
|
scrollController.dispose();
|
||||||
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
@ -239,18 +239,20 @@ class SimpleTableInsertActions extends ISimpleTableBottomSheetActions {
|
|||||||
SimpleTableInsertAction(
|
SimpleTableInsertAction(
|
||||||
type: SimpleTableMoreAction.insertAbove,
|
type: SimpleTableMoreAction.insertAbove,
|
||||||
enableLeftBorder: true,
|
enableLeftBorder: true,
|
||||||
onTap: () => _onActionTap(
|
onTap: (increaseCounter) async => _onActionTap(
|
||||||
context,
|
context,
|
||||||
SimpleTableMoreAction.insertAbove,
|
type: SimpleTableMoreAction.insertAbove,
|
||||||
|
increaseCounter: increaseCounter,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const HSpace(2),
|
const HSpace(2),
|
||||||
SimpleTableInsertAction(
|
SimpleTableInsertAction(
|
||||||
type: SimpleTableMoreAction.insertBelow,
|
type: SimpleTableMoreAction.insertBelow,
|
||||||
enableRightBorder: true,
|
enableRightBorder: true,
|
||||||
onTap: () => _onActionTap(
|
onTap: (increaseCounter) async => _onActionTap(
|
||||||
context,
|
context,
|
||||||
SimpleTableMoreAction.insertBelow,
|
type: SimpleTableMoreAction.insertBelow,
|
||||||
|
increaseCounter: increaseCounter,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -260,18 +262,20 @@ class SimpleTableInsertActions extends ISimpleTableBottomSheetActions {
|
|||||||
SimpleTableInsertAction(
|
SimpleTableInsertAction(
|
||||||
type: SimpleTableMoreAction.insertLeft,
|
type: SimpleTableMoreAction.insertLeft,
|
||||||
enableLeftBorder: true,
|
enableLeftBorder: true,
|
||||||
onTap: () => _onActionTap(
|
onTap: (increaseCounter) async => _onActionTap(
|
||||||
context,
|
context,
|
||||||
SimpleTableMoreAction.insertLeft,
|
type: SimpleTableMoreAction.insertLeft,
|
||||||
|
increaseCounter: increaseCounter,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const HSpace(2),
|
const HSpace(2),
|
||||||
SimpleTableInsertAction(
|
SimpleTableInsertAction(
|
||||||
type: SimpleTableMoreAction.insertRight,
|
type: SimpleTableMoreAction.insertRight,
|
||||||
enableRightBorder: true,
|
enableRightBorder: true,
|
||||||
onTap: () => _onActionTap(
|
onTap: (increaseCounter) async => _onActionTap(
|
||||||
context,
|
context,
|
||||||
SimpleTableMoreAction.insertRight,
|
type: SimpleTableMoreAction.insertRight,
|
||||||
|
increaseCounter: increaseCounter,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -279,7 +283,11 @@ class SimpleTableInsertActions extends ISimpleTableBottomSheetActions {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onActionTap(BuildContext context, SimpleTableMoreAction type) {
|
Future<void> _onActionTap(
|
||||||
|
BuildContext context, {
|
||||||
|
required SimpleTableMoreAction type,
|
||||||
|
required int increaseCounter,
|
||||||
|
}) async {
|
||||||
final simpleTableContext = context.read<SimpleTableContext>();
|
final simpleTableContext = context.read<SimpleTableContext>();
|
||||||
final tableNode = cellNode.parentTableNode;
|
final tableNode = cellNode.parentTableNode;
|
||||||
if (tableNode == null) {
|
if (tableNode == null) {
|
||||||
@ -291,34 +299,48 @@ class SimpleTableInsertActions extends ISimpleTableBottomSheetActions {
|
|||||||
case SimpleTableMoreAction.insertAbove:
|
case SimpleTableMoreAction.insertAbove:
|
||||||
// update the highlight status for the selecting row
|
// update the highlight status for the selecting row
|
||||||
simpleTableContext.selectingRow.value = cellNode.rowIndex + 1;
|
simpleTableContext.selectingRow.value = cellNode.rowIndex + 1;
|
||||||
editorState.insertRowInTable(
|
await editorState.insertRowInTable(
|
||||||
tableNode,
|
tableNode,
|
||||||
cellNode.rowIndex,
|
cellNode.rowIndex,
|
||||||
);
|
);
|
||||||
case SimpleTableMoreAction.insertBelow:
|
case SimpleTableMoreAction.insertBelow:
|
||||||
editorState.insertRowInTable(
|
await editorState.insertRowInTable(
|
||||||
tableNode,
|
tableNode,
|
||||||
cellNode.rowIndex + 1,
|
cellNode.rowIndex + 1,
|
||||||
);
|
);
|
||||||
|
// scroll to the next cell position
|
||||||
|
editorState.scrollService?.scrollTo(
|
||||||
|
SimpleTableConstants.defaultRowHeight,
|
||||||
|
duration: Durations.short3,
|
||||||
|
);
|
||||||
case SimpleTableMoreAction.insertLeft:
|
case SimpleTableMoreAction.insertLeft:
|
||||||
// update the highlight status for the selecting column
|
// update the highlight status for the selecting column
|
||||||
simpleTableContext.selectingColumn.value = cellNode.columnIndex + 1;
|
simpleTableContext.selectingColumn.value = cellNode.columnIndex + 1;
|
||||||
editorState.insertColumnInTable(
|
await editorState.insertColumnInTable(
|
||||||
tableNode,
|
tableNode,
|
||||||
cellNode.columnIndex,
|
cellNode.columnIndex,
|
||||||
);
|
);
|
||||||
case SimpleTableMoreAction.insertRight:
|
case SimpleTableMoreAction.insertRight:
|
||||||
editorState.insertColumnInTable(
|
await editorState.insertColumnInTable(
|
||||||
tableNode,
|
tableNode,
|
||||||
cellNode.columnIndex + 1,
|
cellNode.columnIndex + 1,
|
||||||
);
|
);
|
||||||
|
final horizontalScrollController =
|
||||||
|
simpleTableContext.horizontalScrollController;
|
||||||
|
if (horizontalScrollController != null) {
|
||||||
|
final previousWidth = horizontalScrollController.offset;
|
||||||
|
horizontalScrollController.jumpTo(
|
||||||
|
previousWidth + SimpleTableConstants.defaultColumnWidth,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(false, 'Unsupported action: $type');
|
assert(false, 'Unsupported action: $type');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SimpleTableInsertAction extends StatelessWidget {
|
class SimpleTableInsertAction extends StatefulWidget {
|
||||||
const SimpleTableInsertAction({
|
const SimpleTableInsertAction({
|
||||||
super.key,
|
super.key,
|
||||||
required this.type,
|
required this.type,
|
||||||
@ -330,7 +352,16 @@ class SimpleTableInsertAction extends StatelessWidget {
|
|||||||
final SimpleTableMoreAction type;
|
final SimpleTableMoreAction type;
|
||||||
final bool enableLeftBorder;
|
final bool enableLeftBorder;
|
||||||
final bool enableRightBorder;
|
final bool enableRightBorder;
|
||||||
final void Function() onTap;
|
final ValueChanged<int> onTap;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SimpleTableInsertAction> createState() =>
|
||||||
|
_SimpleTableInsertActionState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SimpleTableInsertActionState extends State<SimpleTableInsertAction> {
|
||||||
|
// used to count how many times the action is tapped
|
||||||
|
int increaseCounter = 0;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -341,19 +372,19 @@ class SimpleTableInsertAction extends StatelessWidget {
|
|||||||
shape: _buildBorder(),
|
shape: _buildBorder(),
|
||||||
),
|
),
|
||||||
child: AnimatedGestureDetector(
|
child: AnimatedGestureDetector(
|
||||||
onTapUp: onTap,
|
onTapUp: () => widget.onTap(increaseCounter++),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(1),
|
padding: const EdgeInsets.all(1),
|
||||||
child: FlowySvg(
|
child: FlowySvg(
|
||||||
type.leftIconSvg,
|
widget.type.leftIconSvg,
|
||||||
size: const Size.square(22),
|
size: const Size.square(22),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
FlowyText(
|
FlowyText(
|
||||||
type.name,
|
widget.type.name,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
figmaLineHeight: 16,
|
figmaLineHeight: 16,
|
||||||
),
|
),
|
||||||
@ -370,10 +401,10 @@ class SimpleTableInsertAction extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
return RoundedRectangleBorder(
|
return RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topLeft: enableLeftBorder ? radius : Radius.zero,
|
topLeft: widget.enableLeftBorder ? radius : Radius.zero,
|
||||||
bottomLeft: enableLeftBorder ? radius : Radius.zero,
|
bottomLeft: widget.enableLeftBorder ? radius : Radius.zero,
|
||||||
topRight: enableRightBorder ? radius : Radius.zero,
|
topRight: widget.enableRightBorder ? radius : Radius.zero,
|
||||||
bottomRight: enableRightBorder ? radius : Radius.zero,
|
bottomRight: widget.enableRightBorder ? radius : Radius.zero,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -592,7 +623,7 @@ class _SimpleTableHeaderActionButtonState
|
|||||||
child: CupertinoSwitch(
|
child: CupertinoSwitch(
|
||||||
value: value,
|
value: value,
|
||||||
activeColor: Theme.of(context).colorScheme.primary,
|
activeColor: Theme.of(context).colorScheme.primary,
|
||||||
onChanged: (_) {},
|
onChanged: (_) => _toggle(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -1198,19 +1229,12 @@ class SimpleTableQuickActions extends StatelessWidget {
|
|||||||
SimpleTableMoreAction.copy,
|
SimpleTableMoreAction.copy,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
FutureBuilder(
|
SimpleTableQuickAction(
|
||||||
future: getIt<ClipboardService>().getData(),
|
type: SimpleTableMoreAction.paste,
|
||||||
builder: (context, snapshot) {
|
onTap: () => _onActionTap(
|
||||||
final hasContent = snapshot.data?.tableJson != null;
|
context,
|
||||||
return SimpleTableQuickAction(
|
SimpleTableMoreAction.paste,
|
||||||
type: SimpleTableMoreAction.paste,
|
),
|
||||||
isEnabled: hasContent,
|
|
||||||
onTap: () => _onActionTap(
|
|
||||||
context,
|
|
||||||
SimpleTableMoreAction.paste,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
SimpleTableQuickAction(
|
SimpleTableQuickAction(
|
||||||
type: SimpleTableMoreAction.delete,
|
type: SimpleTableMoreAction.delete,
|
||||||
|
@ -61,8 +61,8 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: cfb8b1b
|
ref: "9f6a299"
|
||||||
resolved-ref: cfb8b1b6eb06f73a4fb297b6fd1d54b0ccec2922
|
resolved-ref: "9f6a29968ecbb61678b8e0e8c9d90bcba44a24e3"
|
||||||
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
|
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
|
||||||
source: git
|
source: git
|
||||||
version: "4.0.0"
|
version: "4.0.0"
|
||||||
|
@ -174,7 +174,7 @@ dependency_overrides:
|
|||||||
appflowy_editor:
|
appflowy_editor:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/AppFlowy-IO/appflowy-editor.git
|
url: https://github.com/AppFlowy-IO/appflowy-editor.git
|
||||||
ref: "cfb8b1b"
|
ref: "9f6a299"
|
||||||
|
|
||||||
appflowy_editor_plugins:
|
appflowy_editor_plugins:
|
||||||
git:
|
git:
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/simple_table/simple_table.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/simple_table/simple_table.dart';
|
||||||
import 'package:appflowy_backend/log.dart';
|
import 'package:appflowy_backend/log.dart';
|
||||||
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
import 'simple_table_test_helper.dart';
|
import 'simple_table_test_helper.dart';
|
||||||
@ -193,5 +194,45 @@ void main() {
|
|||||||
expect(tableNode.tableAlign, align);
|
expect(tableNode.tableAlign, align);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('clear the existing align of the column before updating', () async {
|
||||||
|
final (editorState, tableNode) = createEditorStateAndTable(
|
||||||
|
rowCount: 2,
|
||||||
|
columnCount: 3,
|
||||||
|
);
|
||||||
|
|
||||||
|
final firstCellNode = tableNode.getTableCellNode(
|
||||||
|
rowIndex: 0,
|
||||||
|
columnIndex: 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
Node firstParagraphNode = firstCellNode!.children.first;
|
||||||
|
|
||||||
|
// format the first paragraph to center align
|
||||||
|
final transaction = editorState.transaction;
|
||||||
|
transaction.updateNode(
|
||||||
|
firstParagraphNode,
|
||||||
|
{
|
||||||
|
blockComponentAlign: TableAlign.right.key,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
await editorState.apply(transaction);
|
||||||
|
|
||||||
|
firstParagraphNode = editorState.getNodeAtPath([0, 0, 0, 0])!;
|
||||||
|
expect(
|
||||||
|
firstParagraphNode.attributes[blockComponentAlign],
|
||||||
|
TableAlign.right.key,
|
||||||
|
);
|
||||||
|
|
||||||
|
await editorState.updateColumnAlign(
|
||||||
|
tableCellNode: firstCellNode,
|
||||||
|
align: TableAlign.center,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
firstParagraphNode.attributes[blockComponentAlign],
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user