feat: support exitting the link menu by pressing ESC

This commit is contained in:
Vincenzo Ursano 2023-07-03 11:05:42 +02:00 • committed by GitHub
commit c8082d38df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 80 additions and 21 deletions

View file

@ -93,6 +93,7 @@
"lightLightTint7": "Green", "lightLightTint7": "Green",
"lightLightTint8": "Aqua", "lightLightTint8": "Aqua",
"lightLightTint9": "Blue", "lightLightTint9": "Blue",
"urlHint": "URL",
"mobileHeading1": "Heading 1", "mobileHeading1": "Heading 1",
"mobileHeading2": "Heading 2", "mobileHeading2": "Heading 2",
"mobileHeading3": "Heading 3", "mobileHeading3": "Heading 3",

View file

@ -2,6 +2,7 @@ import 'package:appflowy_editor/src/editor_state.dart';
import 'package:appflowy_editor/src/infra/flowy_svg.dart'; import 'package:appflowy_editor/src/infra/flowy_svg.dart';
import 'package:appflowy_editor/src/l10n/l10n.dart'; import 'package:appflowy_editor/src/l10n/l10n.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:appflowy_editor/src/editor/toolbar/desktop/items/utils/overlay_util.dart'; import 'package:appflowy_editor/src/editor/toolbar/desktop/items/utils/overlay_util.dart';
class LinkMenu extends StatefulWidget { class LinkMenu extends StatefulWidget {
@ -13,6 +14,7 @@ class LinkMenu extends StatefulWidget {
required this.onOpenLink, required this.onOpenLink,
required this.onCopyLink, required this.onCopyLink,
required this.onRemoveLink, required this.onRemoveLink,
required this.onDismiss,
}) : super(key: key); }) : super(key: key);
final String? linkText; final String? linkText;
@ -21,6 +23,7 @@ class LinkMenu extends StatefulWidget {
final VoidCallback onOpenLink; final VoidCallback onOpenLink;
final VoidCallback onCopyLink; final VoidCallback onCopyLink;
final VoidCallback onRemoveLink; final VoidCallback onRemoveLink;
final VoidCallback onDismiss;
@override @override
State<LinkMenu> createState() => _LinkMenuState(); State<LinkMenu> createState() => _LinkMenuState();
@ -81,13 +84,21 @@ class _LinkMenuState extends State<LinkMenu> {
} }
Widget _buildInput() { Widget _buildInput() {
return TextField( return RawKeyboardListener(
focusNode: FocusNode(),
onKey: (key) {
if (key is RawKeyDownEvent &&
key.logicalKey == LogicalKeyboardKey.escape) {
widget.onDismiss();
}
},
child: TextField(
focusNode: _focusNode, focusNode: _focusNode,
textAlign: TextAlign.left, textAlign: TextAlign.left,
controller: _textEditingController, controller: _textEditingController,
onSubmitted: widget.onSubmitted, onSubmitted: widget.onSubmitted,
decoration: InputDecoration( decoration: InputDecoration(
hintText: 'URL', hintText: AppFlowyEditorLocalizations.current.urlHint,
contentPadding: const EdgeInsets.all(16.0), contentPadding: const EdgeInsets.all(16.0),
isDense: true, isDense: true,
suffixIcon: IconButton( suffixIcon: IconButton(
@ -104,6 +115,7 @@ class _LinkMenuState extends State<LinkMenu> {
borderRadius: BorderRadius.all(Radius.circular(12.0)), borderRadius: BorderRadius.all(Radius.circular(12.0)),
), ),
), ),
),
); );
} }

View file

@ -111,6 +111,7 @@ void showLinkMenu(
editorState.apply(transaction); editorState.apply(transaction);
dismissOverlay(); dismissOverlay();
}, },
onDismiss: dismissOverlay,
); );
}, },
).build(); ).build();

View file

@ -106,6 +106,7 @@ class MessageLookup extends MessageLookupByLibrary {
"tint7": MessageLookupByLibrary.simpleMessage("Tint 7"), "tint7": MessageLookupByLibrary.simpleMessage("Tint 7"),
"tint8": MessageLookupByLibrary.simpleMessage("Tint 8"), "tint8": MessageLookupByLibrary.simpleMessage("Tint 8"),
"tint9": MessageLookupByLibrary.simpleMessage("Tint 9"), "tint9": MessageLookupByLibrary.simpleMessage("Tint 9"),
"underline": MessageLookupByLibrary.simpleMessage("Underline") "underline": MessageLookupByLibrary.simpleMessage("Underline"),
"urlHint": MessageLookupByLibrary.simpleMessage("URL")
}; };
} }

View file

@ -611,6 +611,16 @@ class AppFlowyEditorLocalizations {
); );
} }
/// `URL`
String get urlHint {
return Intl.message(
'URL',
name: 'urlHint',
desc: '',
args: [],
);
}
/// `Heading 1` /// `Heading 1`
String get mobileHeading1 { String get mobileHeading1 {
return Intl.message( return Intl.message(

View file

@ -249,6 +249,7 @@ class _AppFlowySelectionState extends State<AppFlowySelection>
currentSelectedNodes = []; currentSelectedNodes = [];
currentSelection.value = null; currentSelection.value = null;
_clearToolbar();
clearCursor(); clearCursor();
// clear selection areas // clear selection areas
_selectionAreas _selectionAreas

View file

@ -1,6 +1,7 @@
import 'package:appflowy_editor/src/core/document/text_delta.dart'; import 'package:appflowy_editor/src/core/document/text_delta.dart';
import 'package:appflowy_editor/src/editor/toolbar/desktop/items/link/link_menu.dart'; import 'package:appflowy_editor/src/editor/toolbar/desktop/items/link/link_menu.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../../../../infra/testable_editor.dart'; import '../../../../infra/testable_editor.dart';
@ -20,6 +21,7 @@ void main() async {
onSubmitted: (text) { onSubmitted: (text) {
submittedText = text; submittedText = text;
}, },
onDismiss: () {},
); );
final editor = tester.editor; final editor = tester.editor;
await editor.startTesting(); await editor.startTesting();
@ -92,5 +94,36 @@ void main() async {
await editor.dispose(); await editor.dispose();
}); });
testWidgets('test dismiss link menu by pressing ESC', (tester) async {
var dismissed = false;
final linkMenu = LinkMenu(
onOpenLink: () {},
onCopyLink: () {},
onRemoveLink: () {},
onSubmitted: (text) {},
onDismiss: () {
dismissed = true;
},
);
await tester.pumpWidget(
MaterialApp(
home: Material(
child: linkMenu,
),
),
);
expect(find.byType(TextButton), findsNothing);
expect(find.byType(TextField), findsOneWidget);
// Simulate keyboard press event for the Escape key
await tester.sendKeyEvent(LogicalKeyboardKey.escape);
await tester.pumpAndSettle();
expect(dismissed, true);
});
}); });
} }