TF-1155 Handle moving focus between fields using the tab key in advanced search

Signed-off-by: dab246 <tdvu@linagora.com>
(cherry picked from commit 7044a1ca5477390af9d1d7a9003e0d8aae7c632f)
This commit is contained in:
dab246
2023-11-08 12:22:10 +07:00
committed by Dat Vu
parent e41aa811ff
commit bfb35a7187
6 changed files with 82 additions and 123 deletions
@@ -118,7 +118,6 @@ class ComposerView extends GetWidget<ComposerController> {
expandMode: controller.toAddressExpandMode.value,
controller: controller.toEmailAddressController,
focusNode: controller.toAddressFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyToEmailTagEditor,
isInitial: controller.isInitialRecipient.value,
padding: ComposerStyle.mobileRecipientPadding,
@@ -139,7 +138,6 @@ class ComposerView extends GetWidget<ComposerController> {
expandMode: controller.ccAddressExpandMode.value,
controller: controller.ccEmailAddressController,
focusNode: controller.ccAddressFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyCcEmailTagEditor,
isInitial: controller.isInitialRecipient.value,
nextFocusNode: controller.getNextFocusOfCcEmailAddress(),
@@ -160,7 +158,6 @@ class ComposerView extends GetWidget<ComposerController> {
expandMode: controller.bccAddressExpandMode.value,
controller: controller.bccEmailAddressController,
focusNode: controller.bccAddressFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyBccEmailTagEditor,
isInitial: controller.isInitialRecipient.value,
nextFocusNode: controller.subjectEmailInputFocusNode,
@@ -269,7 +266,6 @@ class ComposerView extends GetWidget<ComposerController> {
expandMode: controller.toAddressExpandMode.value,
controller: controller.toEmailAddressController,
focusNode: controller.toAddressFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyToEmailTagEditor,
isInitial: controller.isInitialRecipient.value,
padding: ComposerStyle.mobileRecipientPadding,
@@ -290,7 +286,6 @@ class ComposerView extends GetWidget<ComposerController> {
expandMode: controller.ccAddressExpandMode.value,
controller: controller.ccEmailAddressController,
focusNode: controller.ccAddressFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyCcEmailTagEditor,
isInitial: controller.isInitialRecipient.value,
nextFocusNode: controller.getNextFocusOfCcEmailAddress(),
@@ -311,7 +306,6 @@ class ComposerView extends GetWidget<ComposerController> {
expandMode: controller.bccAddressExpandMode.value,
controller: controller.bccEmailAddressController,
focusNode: controller.bccAddressFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyBccEmailTagEditor,
isInitial: controller.isInitialRecipient.value,
nextFocusNode: controller.subjectEmailInputFocusNode,
@@ -95,7 +95,6 @@ class ComposerView extends GetWidget<ComposerController> {
expandMode: controller.toAddressExpandMode.value,
controller: controller.toEmailAddressController,
focusNode: controller.toAddressFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyToEmailTagEditor,
isInitial: controller.isInitialRecipient.value,
padding: ComposerStyle.mobileRecipientPadding,
@@ -116,7 +115,6 @@ class ComposerView extends GetWidget<ComposerController> {
expandMode: controller.ccAddressExpandMode.value,
controller: controller.ccEmailAddressController,
focusNode: controller.ccAddressFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyCcEmailTagEditor,
isInitial: controller.isInitialRecipient.value,
nextFocusNode: controller.getNextFocusOfCcEmailAddress(),
@@ -137,7 +135,6 @@ class ComposerView extends GetWidget<ComposerController> {
expandMode: controller.bccAddressExpandMode.value,
controller: controller.bccEmailAddressController,
focusNode: controller.bccAddressFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyBccEmailTagEditor,
isInitial: controller.isInitialRecipient.value,
nextFocusNode: controller.subjectEmailInputFocusNode,
@@ -276,7 +273,6 @@ class ComposerView extends GetWidget<ComposerController> {
expandMode: controller.toAddressExpandMode.value,
controller: controller.toEmailAddressController,
focusNode: controller.toAddressFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyToEmailTagEditor,
isInitial: controller.isInitialRecipient.value,
padding: ComposerStyle.desktopRecipientPadding,
@@ -297,7 +293,6 @@ class ComposerView extends GetWidget<ComposerController> {
expandMode: controller.ccAddressExpandMode.value,
controller: controller.ccEmailAddressController,
focusNode: controller.ccAddressFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyCcEmailTagEditor,
isInitial: controller.isInitialRecipient.value,
nextFocusNode: controller.getNextFocusOfCcEmailAddress(),
@@ -318,7 +313,6 @@ class ComposerView extends GetWidget<ComposerController> {
expandMode: controller.bccAddressExpandMode.value,
controller: controller.bccEmailAddressController,
focusNode: controller.bccAddressFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyBccEmailTagEditor,
isInitial: controller.isInitialRecipient.value,
nextFocusNode: controller.subjectEmailInputFocusNode,
@@ -509,7 +503,6 @@ class ComposerView extends GetWidget<ComposerController> {
expandMode: controller.toAddressExpandMode.value,
controller: controller.toEmailAddressController,
focusNode: controller.toAddressFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyToEmailTagEditor,
isInitial: controller.isInitialRecipient.value,
padding: ComposerStyle.tabletRecipientPadding,
@@ -530,7 +523,6 @@ class ComposerView extends GetWidget<ComposerController> {
expandMode: controller.ccAddressExpandMode.value,
controller: controller.ccEmailAddressController,
focusNode: controller.ccAddressFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyCcEmailTagEditor,
isInitial: controller.isInitialRecipient.value,
nextFocusNode: controller.getNextFocusOfCcEmailAddress(),
@@ -551,7 +543,6 @@ class ComposerView extends GetWidget<ComposerController> {
expandMode: controller.bccAddressExpandMode.value,
controller: controller.bccEmailAddressController,
focusNode: controller.bccAddressFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyBccEmailTagEditor,
isInitial: controller.isInitialRecipient.value,
nextFocusNode: controller.subjectEmailInputFocusNode,
@@ -45,7 +45,6 @@ class RecipientComposerWidget extends StatefulWidget {
final PrefixRecipientState bccState;
final bool? isInitial;
final FocusNode? focusNode;
final bool autoDisposeFocusNode;
final GlobalKey? keyTagEditor;
final FocusNode? nextFocusNode;
final TextEditingController? controller;
@@ -71,7 +70,6 @@ class RecipientComposerWidget extends StatefulWidget {
this.isInitial,
this.controller,
this.focusNode,
this.autoDisposeFocusNode = true,
this.expandMode = ExpandMode.EXPAND,
this.keyTagEditor,
this.nextFocusNode,
@@ -165,7 +163,6 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
enableBorder: _isDragging,
borderRadius: RecipientComposerWidgetStyle.enableBorderRadius,
enableBorderColor: RecipientComposerWidgetStyle.enableBorderColor,
autoDisposeFocusNode: widget.autoDisposeFocusNode,
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.done,
debounceDuration: RecipientComposerWidgetStyle.suggestionDebounceDuration,
@@ -240,7 +237,6 @@ class _RecipientComposerWidgetState extends State<RecipientComposerWidget> {
length: _collapsedListEmailAddress.length,
controller: widget.controller,
focusNode: widget.focusNode,
autoDisposeFocusNode: widget.autoDisposeFocusNode,
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.done,
debounceDuration: RecipientComposerWidgetStyle.suggestionDebounceDuration,
@@ -36,13 +36,10 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
controller: controller.fromEmailAddressController,
focusNode: controller.focusManager.fromFieldFocusNode,
nextFocusNode: controller.focusManager.toFieldFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyFromEmailTagEditor,
onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange,
onShowFullListEmailAddressAction: controller.showFullEmailAddress,
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onRemoveEmailAddressAction: controller.removeEmailAddress,
),
TextFieldAutocompleteEmailAddressWeb(
@@ -52,13 +49,10 @@ class AdvancedSearchInputForm extends GetWidget<AdvancedFilterController>
controller: controller.toEmailAddressController,
focusNode: controller.focusManager.toFieldFocusNode,
nextFocusNode: controller.focusManager.subjectFieldFocusNode,
autoDisposeFocusNode: false,
keyTagEditor: controller.keyToEmailTagEditor,
onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange,
onShowFullListEmailAddressAction: controller.showFullEmailAddress,
onUpdateListEmailAddressAction: controller.updateListEmailAddress,
onSuggestionEmailAddress: controller.getAutoCompleteSuggestion,
onFocusNextAddressAction: controller.handleFocusNextAddressAction,
onRemoveEmailAddressAction: controller.removeEmailAddress,
),
_buildFilterField(
@@ -21,7 +21,6 @@ typedef OnSuggestionEmailAddress = Future<List<EmailAddress>> Function(String wo
typedef OnUpdateListEmailAddressAction = void Function(AdvancedSearchFilterField field, List<EmailAddress> newData);
typedef OnDeleteEmailAddressTypeAction = void Function(AdvancedSearchFilterField field);
typedef OnShowFullListEmailAddressAction = void Function(AdvancedSearchFilterField field);
typedef OnFocusEmailAddressChangeAction = void Function(AdvancedSearchFilterField field, bool isFocus);
typedef OnRemoveEmailAddressAction = void Function(EmailAddress emailAddress, AdvancedSearchFilterField field);
typedef OnDeleteTagAction = void Function(EmailAddress emailAddress);
@@ -31,7 +30,6 @@ class TextFieldAutocompleteEmailAddressWeb extends StatefulWidget {
final List<EmailAddress> listEmailAddress;
final ExpandMode expandMode;
final FocusNode? focusNode;
final bool autoDisposeFocusNode;
final GlobalKey? keyTagEditor;
final FocusNode? nextFocusNode;
final EdgeInsetsGeometry? padding;
@@ -41,11 +39,8 @@ class TextFieldAutocompleteEmailAddressWeb extends StatefulWidget {
final OnUpdateListEmailAddressAction? onUpdateListEmailAddressAction;
final OnDeleteEmailAddressTypeAction? onDeleteEmailAddressTypeAction;
final OnShowFullListEmailAddressAction? onShowFullListEmailAddressAction;
final OnFocusEmailAddressChangeAction? onFocusEmailAddressChangeAction;
final OnRemoveEmailAddressAction? onRemoveEmailAddressAction;
final VoidCallback? onFocusNextAddressAction;
final TextEditingController? controller;
final TapRegionCallback? onTapOutside;
const TextFieldAutocompleteEmailAddressWeb({
Key? key,
@@ -53,7 +48,6 @@ class TextFieldAutocompleteEmailAddressWeb extends StatefulWidget {
required this.listEmailAddress,
this.expandMode = ExpandMode.EXPAND,
this.focusNode,
this.autoDisposeFocusNode = true,
this.keyTagEditor,
this.nextFocusNode,
this.padding,
@@ -63,11 +57,8 @@ class TextFieldAutocompleteEmailAddressWeb extends StatefulWidget {
this.onUpdateListEmailAddressAction,
this.onDeleteEmailAddressTypeAction,
this.onShowFullListEmailAddressAction,
this.onFocusEmailAddressChangeAction,
this.onRemoveEmailAddressAction,
this.onFocusNextAddressAction,
this.controller,
this.onTapOutside,
}) : super(key: key);
@override
@@ -111,96 +102,89 @@ class _TextFieldAutocompleteEmailAddressWebState extends State<TextFieldAutocomp
),
const SizedBox(width: TextFieldAutoCompleteEmailAddressWebStyles.space),
Expanded(
child: FocusScope(
child: Focus(
onFocusChange: (focus) {
widget.onFocusEmailAddressChangeAction?.call(widget.field, focus);
},
onKey: (focusNode, event) {
if (event.logicalKey == LogicalKeyboardKey.tab) {
widget.nextFocusNode?.requestFocus();
widget.onFocusNextAddressAction?.call();
return KeyEventResult.handled;
}
return KeyEventResult.ignored;
},
child: StatefulBuilder(
builder: ((context, setState) {
return TagEditor<SuggestionEmailAddress>(
key: widget.keyTagEditor,
length: _collapsedListEmailAddress.length,
controller: widget.controller,
focusNode: widget.focusNode,
autoDisposeFocusNode: widget.autoDisposeFocusNode,
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.done,
debounceDuration: TextFieldAutoCompleteEmailAddressWebStyles.debounceDuration,
hasAddButton: false,
autofocus: widget.field == AdvancedSearchFilterField.form && _currentListEmailAddress.isEmpty,
inputDecoration: InputDecoration(
filled: true,
fillColor: TextFieldAutoCompleteEmailAddressWebStyles.textInputFillColor,
border: TextFieldAutoCompleteEmailAddressWebStyles.textInputBorder,
hintText: widget.field.getHintText(context),
hintStyle: TextFieldAutoCompleteEmailAddressWebStyles.textInputHintStyle,
isDense: true,
contentPadding: TextFieldAutoCompleteEmailAddressWebStyles.textInputContentPadding,
),
padding: TextFieldAutoCompleteEmailAddressWebStyles.tagEditorPadding,
borderRadius: TextFieldAutoCompleteEmailAddressWebStyles.borderRadius,
borderSize: TextFieldAutoCompleteEmailAddressWebStyles.borderWidth,
focusedBorderColor: TextFieldAutoCompleteEmailAddressWebStyles.focusedBorderColor,
enableBorder: true,
enableBorderColor: AppColor.colorInputBorderCreateMailbox,
minTextFieldWidth: TextFieldAutoCompleteEmailAddressWebStyles.minTextFieldWidth,
resetTextOnSubmitted: true,
suggestionsBoxElevation: TextFieldAutoCompleteEmailAddressWebStyles.suggestionBoxElevation,
suggestionsBoxBackgroundColor: TextFieldAutoCompleteEmailAddressWebStyles.suggestionBoxBackgroundColor,
suggestionsBoxRadius: TextFieldAutoCompleteEmailAddressWebStyles.suggestionBoxRadius,
suggestionsBoxMaxHeight: TextFieldAutoCompleteEmailAddressWebStyles.suggestionBoxMaxHeight,
suggestionBoxWidth: _getSuggestionBoxWidth(constraints.maxWidth),
textStyle: TextFieldAutoCompleteEmailAddressWebStyles.textInputTextStyle,
onFocusTagAction: (focused) => _handleFocusTagAction.call(focused, setState),
onDeleteTagAction: () => _handleDeleteLatestTagAction.call(setState),
onSelectOptionAction: (item) => _handleSelectOptionAction.call(item, setState),
onSubmitted: (value) => _handleSubmitTagAction.call(value, setState),
onTapOutside: widget.onTapOutside,
tagBuilder: (context, index) {
final currentEmailAddress = _currentListEmailAddress.elementAt(index);
final isLatestEmail = currentEmailAddress == _currentListEmailAddress.last;
return AutoCompleteTagItemWidgetWeb(
field: widget.field,
currentEmailAddress: currentEmailAddress,
currentListEmailAddress: _currentListEmailAddress,
collapsedListEmailAddress: _collapsedListEmailAddress,
isLatestEmail: isLatestEmail,
isCollapsed: _isCollapse,
isLatestTagFocused: _lastTagFocused,
onDeleteTagAction: (emailAddress) => _handleDeleteTagAction.call(emailAddress, setState),
onShowFullAction: widget.onShowFullListEmailAddressAction,
);
},
onTagChanged: (tag) => _handleOnTagChangeAction.call(tag, setState),
findSuggestions: _findSuggestions,
useDefaultHighlight: true,
suggestionBuilder: (context, tagEditorState, suggestionEmailAddress, index, length, highlight, suggestionValid) {
return AutoCompleteSuggestionItemWidgetWeb(
suggestionState: suggestionEmailAddress.state,
emailAddress: suggestionEmailAddress.emailAddress,
suggestionValid: suggestionValid,
highlight: highlight,
onSelectedAction: (emailAddress) {
setState(() => _currentListEmailAddress.add(emailAddress));
_updateListEmailAddressAction();
tagEditorState.resetTextField();
tagEditorState.closeSuggestionBox();
},
);
child: StatefulBuilder(
builder: ((context, setState) {
return TagEditor<SuggestionEmailAddress>(
key: widget.keyTagEditor,
length: _collapsedListEmailAddress.length,
controller: widget.controller,
focusNodeKeyboard: widget.focusNode,
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.done,
debounceDuration: TextFieldAutoCompleteEmailAddressWebStyles.debounceDuration,
hasAddButton: false,
autofocus: widget.field == AdvancedSearchFilterField.form && _currentListEmailAddress.isEmpty,
inputDecoration: InputDecoration(
filled: true,
fillColor: TextFieldAutoCompleteEmailAddressWebStyles.textInputFillColor,
border: TextFieldAutoCompleteEmailAddressWebStyles.textInputBorder,
hintText: widget.field.getHintText(context),
hintStyle: TextFieldAutoCompleteEmailAddressWebStyles.textInputHintStyle,
isDense: true,
contentPadding: TextFieldAutoCompleteEmailAddressWebStyles.textInputContentPadding,
),
padding: TextFieldAutoCompleteEmailAddressWebStyles.tagEditorPadding,
borderRadius: TextFieldAutoCompleteEmailAddressWebStyles.borderRadius,
borderSize: TextFieldAutoCompleteEmailAddressWebStyles.borderWidth,
focusedBorderColor: TextFieldAutoCompleteEmailAddressWebStyles.focusedBorderColor,
enableBorder: true,
enableBorderColor: AppColor.colorInputBorderCreateMailbox,
minTextFieldWidth: TextFieldAutoCompleteEmailAddressWebStyles.minTextFieldWidth,
resetTextOnSubmitted: true,
suggestionsBoxElevation: TextFieldAutoCompleteEmailAddressWebStyles.suggestionBoxElevation,
suggestionsBoxBackgroundColor: TextFieldAutoCompleteEmailAddressWebStyles.suggestionBoxBackgroundColor,
suggestionsBoxRadius: TextFieldAutoCompleteEmailAddressWebStyles.suggestionBoxRadius,
suggestionsBoxMaxHeight: TextFieldAutoCompleteEmailAddressWebStyles.suggestionBoxMaxHeight,
suggestionBoxWidth: _getSuggestionBoxWidth(constraints.maxWidth),
textStyle: TextFieldAutoCompleteEmailAddressWebStyles.textInputTextStyle,
onFocusTagAction: (focused) => _handleFocusTagAction.call(focused, setState),
onDeleteTagAction: () => _handleDeleteLatestTagAction.call(setState),
onSelectOptionAction: (item) => _handleSelectOptionAction.call(item, setState),
onSubmitted: (value) => _handleSubmitTagAction.call(value, setState),
tagBuilder: (context, index) {
final currentEmailAddress = _currentListEmailAddress.elementAt(index);
final isLatestEmail = currentEmailAddress == _currentListEmailAddress.last;
return AutoCompleteTagItemWidgetWeb(
field: widget.field,
currentEmailAddress: currentEmailAddress,
currentListEmailAddress: _currentListEmailAddress,
collapsedListEmailAddress: _collapsedListEmailAddress,
isLatestEmail: isLatestEmail,
isCollapsed: _isCollapse,
isLatestTagFocused: _lastTagFocused,
onDeleteTagAction: (emailAddress) => _handleDeleteTagAction.call(emailAddress, setState),
onShowFullAction: widget.onShowFullListEmailAddressAction,
);
},
onTagChanged: (tag) => _handleOnTagChangeAction.call(tag, setState),
findSuggestions: _findSuggestions,
suggestionBuilder: (context, tagEditorState, suggestionEmailAddress, index, length, highlight, suggestionValid) {
return AutoCompleteSuggestionItemWidgetWeb(
suggestionState: suggestionEmailAddress.state,
emailAddress: suggestionEmailAddress.emailAddress,
suggestionValid: suggestionValid,
highlight: highlight,
onSelectedAction: (emailAddress) {
setState(() => _currentListEmailAddress.add(emailAddress));
_updateListEmailAddressAction();
tagEditorState.resetTextField();
tagEditorState.closeSuggestionBox();
},
);
})
),
)
},
onHandleKeyEventAction: (event) {
if (event is RawKeyDownEvent) {
switch (event.logicalKey) {
case LogicalKeyboardKey.tab:
widget.nextFocusNode?.requestFocus();
break;
default:
break;
}
}
},
);
})
),
),
],
+1 -1
View File
@@ -1553,7 +1553,7 @@ packages:
description:
path: "."
ref: master
resolved-ref: "796d679e3aaf34d0107819d1f12bb3cf45a59d64"
resolved-ref: aad6fb53c832fbe3b86f2b9eaefaab7a83392529
url: "https://github.com/dab246/super_tag_editor.git"
source: git
version: "0.2.0"