TF-2101 Add suggestion tag for input field with suggestion
(cherry picked from commit 9a4847aefae5554710999e6fdf98ed0f7f8eca3c)
This commit is contained in:
+12
@@ -0,0 +1,12 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class AvatarTagItemWidgetStyles {
|
||||||
|
static const double size = 24.0;
|
||||||
|
static const double borderWidth = 0.21;
|
||||||
|
|
||||||
|
static const TextStyle textStyle = TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 8.57,
|
||||||
|
fontWeight: FontWeight.w600
|
||||||
|
);
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SuggestionTagItemWidgetStyles {
|
||||||
|
static const double paddingTop = 4.5;
|
||||||
|
static const double paddingEndCollapsed = 40.0;
|
||||||
|
static const double paddingEndExpanded = 0.0;
|
||||||
|
static const double labelPaddingHorizontal = 4.0;
|
||||||
|
static const double labelPaddingVertical = 2.0;
|
||||||
|
static const double collapsedTextBorderRadius = 10.0;
|
||||||
|
|
||||||
|
static const BorderRadius borderRadius = BorderRadius.all(Radius.circular(10));
|
||||||
|
|
||||||
|
static const EdgeInsetsGeometry collapsedTextMargin = EdgeInsets.only(
|
||||||
|
top: 5.5,
|
||||||
|
);
|
||||||
|
static const EdgeInsetsGeometry collapsedTextPadding = EdgeInsetsDirectional.symmetric(
|
||||||
|
vertical: 5,
|
||||||
|
horizontal: 8,
|
||||||
|
);
|
||||||
|
|
||||||
|
static const BorderSide latestTagBorderSide = BorderSide(
|
||||||
|
color: AppColor.primaryColor,
|
||||||
|
width: 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
static const TextStyle labelStyle = TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 17,
|
||||||
|
fontWeight: FontWeight.w400
|
||||||
|
);
|
||||||
|
}
|
||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:tmail_ui_user/features/email_recovery/presentation/styles/text_input_field/avatar_tag_item_widget_styles.dart';
|
||||||
|
|
||||||
|
class AvatarTagItemWidget extends StatelessWidget {
|
||||||
|
final String tagName;
|
||||||
|
|
||||||
|
const AvatarTagItemWidget({super.key, required this.tagName});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
width: AvatarTagItemWidgetStyles.size,
|
||||||
|
height: AvatarTagItemWidgetStyles.size,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
colors:AppColor.mapGradientColor[_generateIndex(tagName)]
|
||||||
|
),
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColor.colorShadowBgContentEmail,
|
||||||
|
width: AvatarTagItemWidgetStyles.borderWidth
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
tagName.isNotEmpty ? tagName[0].toUpperCase() : '',
|
||||||
|
style: AvatarTagItemWidgetStyles.textStyle
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _generateIndex(String tag) {
|
||||||
|
if (tag.isNotEmpty) {
|
||||||
|
final codeUnits = tag.codeUnits;
|
||||||
|
if (codeUnits.isNotEmpty) {
|
||||||
|
final sumCodeUnits = codeUnits.sum;
|
||||||
|
final index = sumCodeUnits % AppColor.mapGradientColor.length;
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
+122
@@ -0,0 +1,122 @@
|
|||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
|
import 'package:core/presentation/utils/style_utils.dart';
|
||||||
|
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
||||||
|
import 'package:core/utils/direction_utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||||
|
import 'package:model/model.dart';
|
||||||
|
import 'package:tmail_ui_user/features/email_recovery/presentation/model/email_recovery_field.dart';
|
||||||
|
import 'package:tmail_ui_user/features/email_recovery/presentation/styles/text_input_field/suggestion_tag_item_widget_styles.dart';
|
||||||
|
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/text_input_field/avatar_tag_item_widget.dart';
|
||||||
|
import 'package:tmail_ui_user/features/email_recovery/presentation/widgets/text_input_field/text_input_field_suggestion_widget.dart';
|
||||||
|
|
||||||
|
class SuggestionTagItemWidget extends StatelessWidget {
|
||||||
|
final bool isCollapsed;
|
||||||
|
final bool isLatestTagFocused;
|
||||||
|
final bool isLatestEmail;
|
||||||
|
final EmailRecoveryField field;
|
||||||
|
final EmailAddress currentEmailAddress;
|
||||||
|
final List<EmailAddress> currentListEmailAddress;
|
||||||
|
final List<EmailAddress> collapsedListEmailAddress;
|
||||||
|
final OnDeleteTagAction? onDeleteTagAction;
|
||||||
|
final OnShowFullListEmailAddressAction? onShowFullAction;
|
||||||
|
|
||||||
|
final _imagePaths = Get.find<ImagePaths>();
|
||||||
|
|
||||||
|
SuggestionTagItemWidget({
|
||||||
|
super.key,
|
||||||
|
required this.field,
|
||||||
|
required this.currentEmailAddress,
|
||||||
|
required this.currentListEmailAddress,
|
||||||
|
required this.collapsedListEmailAddress,
|
||||||
|
this.isCollapsed = false,
|
||||||
|
this.isLatestTagFocused = false,
|
||||||
|
this.isLatestEmail = false,
|
||||||
|
this.onDeleteTagAction,
|
||||||
|
this.onShowFullAction,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Stack(
|
||||||
|
alignment: AlignmentDirectional.centerEnd,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsetsDirectional.only(
|
||||||
|
top: SuggestionTagItemWidgetStyles.paddingTop,
|
||||||
|
end: isCollapsed
|
||||||
|
? SuggestionTagItemWidgetStyles.paddingEndCollapsed
|
||||||
|
: SuggestionTagItemWidgetStyles.paddingEndExpanded,
|
||||||
|
),
|
||||||
|
child: TextFieldTapRegion(
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () => isCollapsed
|
||||||
|
? onShowFullAction?.call(field)
|
||||||
|
: null,
|
||||||
|
child: MouseRegion(
|
||||||
|
cursor: SystemMouseCursors.grab,
|
||||||
|
child: Chip(
|
||||||
|
labelPadding: EdgeInsetsDirectional.symmetric(
|
||||||
|
horizontal: SuggestionTagItemWidgetStyles.labelPaddingHorizontal,
|
||||||
|
vertical: DirectionUtils.isDirectionRTLByHasAnyRtl(currentEmailAddress.asString())
|
||||||
|
? 0
|
||||||
|
: SuggestionTagItemWidgetStyles.labelPaddingVertical,
|
||||||
|
),
|
||||||
|
label: Text(
|
||||||
|
currentEmailAddress.asString(),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: CommonTextStyle.defaultTextOverFlow,
|
||||||
|
softWrap: CommonTextStyle.defaultSoftWrap,
|
||||||
|
),
|
||||||
|
deleteIcon: SvgPicture.asset(
|
||||||
|
_imagePaths.icClose,
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
labelStyle: SuggestionTagItemWidgetStyles.labelStyle,
|
||||||
|
backgroundColor: _getTagBackgroundColor(),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: SuggestionTagItemWidgetStyles.borderRadius,
|
||||||
|
side: _getTagBorderSide(),
|
||||||
|
),
|
||||||
|
avatar: currentEmailAddress.emailAddress.isNotEmpty
|
||||||
|
? AvatarTagItemWidget(tagName: currentEmailAddress.emailAddress)
|
||||||
|
: null,
|
||||||
|
onDeleted: () => onDeleteTagAction?.call(currentEmailAddress),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (isCollapsed)
|
||||||
|
TMailButtonWidget.fromText(
|
||||||
|
margin: SuggestionTagItemWidgetStyles.collapsedTextMargin,
|
||||||
|
text: '+${currentListEmailAddress.length - collapsedListEmailAddress.length}',
|
||||||
|
onTapActionCallback: () => onShowFullAction?.call(field),
|
||||||
|
borderRadius: SuggestionTagItemWidgetStyles.collapsedTextBorderRadius,
|
||||||
|
textStyle: SuggestionTagItemWidgetStyles.labelStyle,
|
||||||
|
padding: SuggestionTagItemWidgetStyles.collapsedTextPadding,
|
||||||
|
backgroundColor: AppColor.colorEmailAddressTag,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Color _getTagBackgroundColor() {
|
||||||
|
if (isLatestTagFocused && isLatestEmail) {
|
||||||
|
return AppColor.colorItemRecipientSelected;
|
||||||
|
} else {
|
||||||
|
return AppColor.colorEmailAddressTag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BorderSide _getTagBorderSide() {
|
||||||
|
if (isLatestTagFocused && isLatestEmail) {
|
||||||
|
return SuggestionTagItemWidgetStyles.latestTagBorderSide;
|
||||||
|
} else {
|
||||||
|
return BorderSide.none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user