TF-1694 Upgrade dropdown_button2 to version 2.0.0

(cherry picked from commit 84694b719bcd94a90282146bdc1c173c0e3fbd7e)
This commit is contained in:
dab246
2023-04-06 22:45:38 +07:00
committed by Dat Vu
parent fb307b72c8
commit 28a79a0b76
12 changed files with 363 additions and 331 deletions
@@ -130,33 +130,40 @@ class DropDownButtonWidget<T> extends StatelessWidget {
) )
: null, : null,
onChanged: onChanged, onChanged: onChanged,
icon: iconArrowDown ?? SvgPicture.asset(imagePaths.icDropDown), buttonStyleData: ButtonStyleData(
buttonPadding: const EdgeInsets.symmetric(horizontal: 12), height: heightItem,
buttonDecoration: BoxDecoration( padding: const EdgeInsets.symmetric(horizontal: 12),
borderRadius: BorderRadius.circular(radiusButton), decoration: BoxDecoration(
border: Border.all( borderRadius: BorderRadius.circular(radiusButton),
color: AppColor.colorInputBorderCreateMailbox, border: Border.all(
width: 1, color: AppColor.colorInputBorderCreateMailbox,
width: 1,
),
color: colorButton,
)
),
dropdownStyleData: DropdownStyleData(
maxHeight: dropdownMaxHeight ?? 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(radiusButton),
color: Colors.white,
),
width: dropdownWidth,
elevation: 4,
offset: const Offset(0.0, -8.0),
scrollbarTheme: ScrollbarThemeData(
radius: const Radius.circular(40),
thickness: MaterialStateProperty.all<double>(6),
thumbVisibility: MaterialStateProperty.all<bool>(true),
), ),
color: colorButton,
), ),
itemHeight: heightItem, iconStyleData: IconStyleData(icon: iconArrowDown ?? SvgPicture.asset(imagePaths.icDropDown)),
buttonHeight: heightItem, menuItemStyleData: MenuItemStyleData(
selectedItemHighlightColor: supportSelectionIcon height: heightItem,
? Colors.white padding: const EdgeInsets.symmetric(horizontal: 12),
: Colors.black12, overlayColor: MaterialStateProperty.resolveWith<Color>((Set<MaterialState> states) => supportSelectionIcon ? Colors.white : Colors.black12)
itemPadding: const EdgeInsets.symmetric(horizontal: 12),
dropdownMaxHeight: dropdownMaxHeight ?? 200,
dropdownDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(radiusButton),
color: Colors.white,
), ),
offset: const Offset(0.0, -8.0),
dropdownElevation: 4,
scrollbarRadius: const Radius.circular(40),
scrollbarThickness: 6,
onMenuStateChange: onMenuStateChange, onMenuStateChange: onMenuStateChange,
dropdownWidth: dropdownWidth,
), ),
), ),
); );
@@ -314,16 +314,23 @@ class ComposerView extends GetWidget<ComposerController>
), ),
)).toList(), )).toList(),
onChanged: (newIdentity) => controller.selectIdentity(newIdentity), onChanged: (newIdentity) => controller.selectIdentity(newIdentity),
itemPadding: const EdgeInsets.symmetric(horizontal: 8), dropdownStyleData: DropdownStyleData(
itemHeight: 55, maxHeight: 240,
dropdownMaxHeight: 240, width: 300,
dropdownWidth: 300, decoration: BoxDecoration(
dropdownDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
color: Colors.white), color: Colors.white),
dropdownElevation: 4, elevation: 4,
scrollbarRadius: const Radius.circular(40), scrollbarTheme: ScrollbarThemeData(
scrollbarThickness: 6, radius: const Radius.circular(40),
thickness: MaterialStateProperty.all<double>(6),
thumbVisibility: MaterialStateProperty.all<bool>(true),
),
),
menuItemStyleData: const MenuItemStyleData(
height: 55,
padding: EdgeInsets.symmetric(horizontal: 8),
)
), ),
), ),
Expanded(child: Padding( Expanded(child: Padding(
@@ -504,16 +504,23 @@ class ComposerView extends GetWidget<ComposerController>
), ),
)).toList(), )).toList(),
onChanged: (newIdentity) => controller.selectIdentity(newIdentity), onChanged: (newIdentity) => controller.selectIdentity(newIdentity),
itemPadding: const EdgeInsets.symmetric(horizontal: 8), dropdownStyleData: DropdownStyleData(
itemHeight: 55, maxHeight: 240,
dropdownMaxHeight: 240, width: 370,
dropdownWidth: 370, decoration: BoxDecoration(
dropdownDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
color: Colors.white), color: Colors.white),
dropdownElevation: 4, elevation: 4,
scrollbarRadius: const Radius.circular(40), scrollbarTheme: ScrollbarThemeData(
scrollbarThickness: 6, radius: const Radius.circular(40),
thickness: MaterialStateProperty.all<double>(6),
thumbVisibility: MaterialStateProperty.all<bool>(true),
),
),
menuItemStyleData: const MenuItemStyleData(
height: 55,
padding: EdgeInsets.symmetric(horizontal: 8),
)
), ),
), ),
Expanded(child: Padding( Expanded(child: Padding(
@@ -47,19 +47,25 @@ class DropDownMenuHeaderStyleWidget extends StatelessWidget {
customButton: icon, customButton: icon,
onChanged: onChanged, onChanged: onChanged,
onMenuStateChange: onMenuStateChange, onMenuStateChange: onMenuStateChange,
itemHeight: heightItem, buttonStyleData: ButtonStyleData(height: heightItem),
buttonHeight: heightItem, dropdownStyleData: DropdownStyleData(
itemPadding: const EdgeInsets.symmetric(horizontal: 12), maxHeight: 200,
dropdownWidth: dropdownWidth, width: dropdownWidth,
dropdownMaxHeight: 200, decoration: BoxDecoration(
dropdownDecoration: BoxDecoration( borderRadius: BorderRadius.circular(5),
borderRadius: BorderRadius.circular(5), color: Colors.white),
color: Colors.white, elevation: 4,
offset: const Offset(0.0, -8.0),
scrollbarTheme: ScrollbarThemeData(
radius: const Radius.circular(40),
thickness: MaterialStateProperty.all<double>(6),
thumbVisibility: MaterialStateProperty.all<bool>(true),
)
), ),
offset: const Offset(0.0, -8.0), menuItemStyleData: MenuItemStyleData(
dropdownElevation: 4, height: heightItem,
scrollbarRadius: const Radius.circular(40), padding: const EdgeInsets.symmetric(horizontal: 12)
scrollbarThickness: 6, )
), ),
), ),
); );
@@ -1,6 +1,14 @@
import 'dart:math'; import 'dart:math' as math;
import 'package:core/core.dart'; import 'package:core/presentation/extensions/capitalize_extension.dart';
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/html_transformer/html_template.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/presentation/views/responsive/responsive_widget.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/build_utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@@ -177,7 +185,7 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: Colors.white, color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(16))), borderRadius: BorderRadius.all(Radius.circular(16))),
width: max(_responsiveUtils.getSizeScreenWidth(context) * 0.4, 650), width: math.max(_responsiveUtils.getSizeScreenWidth(context) * 0.4, 650),
height: _responsiveUtils.getSizeScreenHeight(context) * 0.75, height: _responsiveUtils.getSizeScreenHeight(context) * 0.75,
child: ClipRRect( child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(16)), borderRadius: const BorderRadius.all(Radius.circular(16)),
@@ -197,64 +205,58 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
child: Padding( child: Padding(
padding: const EdgeInsets.all(24.0), padding: const EdgeInsets.all(24.0),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Obx(() => (IdentityInputFieldBuilder( Obx(() => IdentityInputFieldBuilder(
AppLocalizations.of(context).name, AppLocalizations.of(context).name,
controller.errorNameIdentity.value, controller.errorNameIdentity.value,
AppLocalizations.of(context).required, AppLocalizations.of(context).required,
editingController: controller.inputNameIdentityController, editingController: controller.inputNameIdentityController,
focusNode: controller.inputNameIdentityFocusNode, focusNode: controller.inputNameIdentityFocusNode,
isMandatory: true) isMandatory: true,
..addOnChangeInputNameAction((value) => controller.updateNameIdentity(context, value))) onChangeInputNameAction: (value) => controller.updateNameIdentity(context, value)
.build()), )),
const SizedBox(height: 24), const SizedBox(height: 24),
Obx(() { Obx(() {
if (controller.actionType.value == IdentityActionType.create) { if (controller.actionType.value == IdentityActionType.create) {
return (IdentityDropListFieldBuilder( return IdentityDropListFieldBuilder(
_imagePaths, _imagePaths,
AppLocalizations.of(context).email.inCaps, AppLocalizations.of(context).email.inCaps,
controller.emailOfIdentity.value, controller.emailOfIdentity.value,
controller.listEmailAddressDefault) controller.listEmailAddressDefault,
..addOnSelectEmailAddressDropListAction((emailAddress) => onSelectItemDropList: controller.updateEmailOfIdentity);
controller.updateEmailOfIdentity(emailAddress))
).build();
} else { } else {
return IdentityFieldNoEditableBuilder( return IdentityFieldNoEditableBuilder(
AppLocalizations.of(context).email.inCaps, AppLocalizations.of(context).email.inCaps,
controller.emailOfIdentity.value controller.emailOfIdentity.value);
).build();
} }
}), }),
const SizedBox(height: 24), const SizedBox(height: 24),
Obx(() => (IdentityDropListFieldBuilder( Obx(() => IdentityDropListFieldBuilder(
_imagePaths, _imagePaths,
AppLocalizations.of(context).reply_to, AppLocalizations.of(context).reply_to,
controller.replyToOfIdentity.value, controller.replyToOfIdentity.value,
controller.listEmailAddressOfReplyTo) controller.listEmailAddressOfReplyTo,
..addOnSelectEmailAddressDropListAction((newEmailAddress) => onSelectItemDropList: controller.updaterReplyToOfIdentity
controller.updaterReplyToOfIdentity(newEmailAddress))) )),
.build()),
const SizedBox(height: 24), const SizedBox(height: 24),
Obx(() => (IdentityInputWithDropListFieldBuilder( Obx(() => IdentityInputWithDropListFieldBuilder(
AppLocalizations.of(context).bcc_to, AppLocalizations.of(context).bcc_to,
controller.errorBccIdentity.value, controller.errorBccIdentity.value,
controller.inputBccIdentityController, controller.inputBccIdentityController,
focusNode: controller.inputBccIdentityFocusNode) focusNode: controller.inputBccIdentityFocusNode,
..addOnSelectedSuggestionAction((newEmailAddress) { onSelectedSuggestionAction: (newEmailAddress) {
controller.inputBccIdentityController?.text = newEmailAddress?.email ?? ''; controller.inputBccIdentityController?.text = newEmailAddress?.email ?? '';
controller.updateBccOfIdentity(newEmailAddress); controller.updateBccOfIdentity(newEmailAddress);
}) },
..addOnChangeInputSuggestionAction((pattern) { onChangeInputSuggestionAction: (pattern) {
controller.validateInputBccAddress(context, pattern); controller.validateInputBccAddress(context, pattern);
if (pattern == null || pattern.trim().isEmpty) { if (pattern == null || pattern.trim().isEmpty) {
controller.updateBccOfIdentity(null); controller.updateBccOfIdentity(null);
} else { } else {
controller.updateBccOfIdentity(EmailAddress(null, pattern)); controller.updateBccOfIdentity(EmailAddress(null, pattern));
} }
}) },
..addOnSuggestionCallbackAction((pattern) => onSuggestionCallbackAction: controller.getSuggestionEmailAddress
controller.getSuggestionEmailAddress(pattern))) )),
.build()
),
const SizedBox(height: 32), const SizedBox(height: 32),
Text(AppLocalizations.of(context).signature, Text(AppLocalizations.of(context).signature,
style: const TextStyle( style: const TextStyle(
@@ -271,78 +273,10 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
), ),
child: _buildSignatureHtmlTemplate(context), child: _buildSignatureHtmlTemplate(context),
), ),
if (_responsiveUtils.isTablet(context) || _responsiveUtils.isMobile(context))...[ if (_isMobile(context))
Obx(() { _buildActionButtonMobile(context)
if (controller.isDefaultIdentitySupported.isTrue) { else
return Padding( _buildActionButtonDesktop(context)
padding: const EdgeInsets.only(top: 27),
child: SetDefaultIdentityCheckboxBuilder(
imagePaths: _imagePaths,
isCheck: controller.isDefaultIdentity.value,
onCheckboxChanged: controller.onCheckboxChanged
)
);
} else {
return const SizedBox.shrink();
}
}),
const SizedBox(height: 24),
Container(
alignment: Alignment.center,
color: Colors.white,
child: Row(
children: [
Expanded(
child: buildTextButton(
AppLocalizations.of(context).cancel,
textStyle: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 17,
color: AppColor.colorTextButton,
),
backgroundColor: AppColor.emailAddressChipColor,
width: 128,
height: 44,
radius: 10,
onTap: () => controller.closeView(context),
),
),
const SizedBox(width: 12),
Expanded(
child: Obx(() => controller.viewState.value.fold(
(failure) => buildTextButton(
controller.actionType.value == IdentityActionType.create
? AppLocalizations.of(context).create
: AppLocalizations.of(context).save,
width: 128,
height: 44,
radius: 10,
onTap: () => controller.createNewIdentity(context)),
(success) {
if (success is GetAllIdentitiesLoading) {
return const Center(
key: Key('create_loading_icon'),
child: CircularProgressIndicator(color: AppColor.primaryColor));
} else {
return buildTextButton(
controller.actionType.value == IdentityActionType.create
? AppLocalizations.of(context).create
: AppLocalizations.of(context).save,
width: 128,
height: 44,
radius: 10,
onTap: () => controller.createNewIdentity(context));
}
}
)),
),
]
),
),
const SizedBox(height: 35),
] else ...[
_buildActionBottomDesktop(context)
]
]), ]),
), ),
); );
@@ -478,20 +412,10 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
); );
} }
Widget _buildActionBottomDesktop(BuildContext context) { Widget _buildActionButtonDesktop(BuildContext context) {
return Row( return Row(
children: [ children: [
Obx(() { _buildCheckboxIdentityDefault(context),
if (controller.isDefaultIdentitySupported.isTrue) {
return SetDefaultIdentityCheckboxBuilder(
imagePaths: _imagePaths,
isCheck: controller.isDefaultIdentity.value,
onCheckboxChanged: controller.onCheckboxChanged
);
} else {
return const SizedBox.shrink();
}
}),
Expanded( Expanded(
child: Padding( child: Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(
@@ -508,28 +432,9 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
right: AppUtils.isDirectionRTL(context) ? 0 : 12, right: AppUtils.isDirectionRTL(context) ? 0 : 12,
left: AppUtils.isDirectionRTL(context) ? 12 : 0 left: AppUtils.isDirectionRTL(context) ? 12 : 0
), ),
child: buildTextButton( child: _buildCancelButton(context, width: 156),
AppLocalizations.of(context).cancel,
textStyle: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 17,
color: AppColor.colorTextButton,
),
backgroundColor: AppColor.emailAddressChipColor,
width: 156,
height: 44,
radius: 10,
onTap: () => controller.closeView(context),
),
), ),
buildTextButton( _buildSaveButton(context, width: 156),
controller.actionType.value == IdentityActionType.create
? AppLocalizations.of(context).create
: AppLocalizations.of(context).save,
width: 156,
height: 44,
radius: 10,
onTap: () => controller.createNewIdentity(context)),
], ],
), ),
), ),
@@ -537,4 +442,80 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
], ],
); );
} }
Widget _buildActionButtonMobile(BuildContext context) {
return Column(children: [
_buildCheckboxIdentityDefault(context),
Container(
alignment: Alignment.center,
color: Colors.white,
padding: const EdgeInsets.only(top: 24, bottom: 35),
child: Row(children: [
Expanded(child: _buildCancelButton(context)),
const SizedBox(width: 12),
Expanded(child: _buildSaveButton(context))
]),
)
]);
}
Widget _buildCheckboxIdentityDefault(BuildContext context) {
return Obx(() {
if (controller.isDefaultIdentitySupported.isTrue) {
return SetDefaultIdentityCheckboxBuilder(
imagePaths: _imagePaths,
isCheck: controller.isDefaultIdentity.value,
onCheckboxChanged: controller.onCheckboxChanged);
} else {
return const SizedBox.shrink();
}
});
}
Widget _buildCancelButton(BuildContext context, {double? width}) {
return buildTextButton(
AppLocalizations.of(context).cancel,
textStyle: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 17,
color: AppColor.colorTextButton,
),
backgroundColor: AppColor.emailAddressChipColor,
width: width ?? 128,
height: 44,
radius: 10,
onTap: () => controller.closeView(context),
);
}
Widget _buildSaveButton(BuildContext context, {double? width}) {
return Obx(() => controller.viewState.value.fold(
(failure) => buildTextButton(
controller.actionType.value == IdentityActionType.create
? AppLocalizations.of(context).create
: AppLocalizations.of(context).save,
width: width ?? 128,
height: 44,
radius: 10,
onTap: () => controller.createNewIdentity(context)),
(success) {
if (success is GetAllIdentitiesLoading) {
return const Center(
key: Key('create_loading_icon'),
child: CircularProgressIndicator(color: AppColor.primaryColor));
} else {
return buildTextButton(
controller.actionType.value == IdentityActionType.create
? AppLocalizations.of(context).create
: AppLocalizations.of(context).save,
width: width ?? 128,
height: 44,
radius: 10,
onTap: () => controller.createNewIdentity(context));
}
}
));
}
bool _isMobile(BuildContext context) => _responsiveUtils.isPortraitMobile(context) || _responsiveUtils.isLandscapeMobile(context);
} }
@@ -1,47 +1,50 @@
import 'package:core/core.dart'; 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:dropdown_button2/dropdown_button2.dart'; import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/extensions/email_address_extension.dart';
typedef OnSelectEmailAddressDropListAction = Function(EmailAddress? emailAddress); typedef OnSelectEmailAddressDropListAction = Function(EmailAddress? emailAddress);
class IdentityDropListFieldBuilder { class IdentityDropListFieldBuilder extends StatelessWidget {
final ImagePaths _imagePaths; final ImagePaths _imagePaths;
final String _label; final String _label;
final EmailAddress? _emailAddressSelected; final EmailAddress? _emailAddressSelected;
final List<EmailAddress> _listEmailAddress; final List<EmailAddress> _listEmailAddress;
final OnSelectEmailAddressDropListAction? onSelectItemDropList;
OnSelectEmailAddressDropListAction? onSelectItemDropList; const IdentityDropListFieldBuilder(
IdentityDropListFieldBuilder(
this._imagePaths, this._imagePaths,
this._label, this._label,
this._emailAddressSelected, this._emailAddressSelected,
this._listEmailAddress, this._listEmailAddress, {
); super.key,
this.onSelectItemDropList
});
void addOnSelectEmailAddressDropListAction(OnSelectEmailAddressDropListAction action) { @override
onSelectItemDropList = action; Widget build(BuildContext context) {
}
Widget build() {
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(_label, style: const TextStyle( Text(
fontSize: 14, _label,
fontWeight: FontWeight.normal, style: const TextStyle(
color: AppColor.colorContentEmail)), fontSize: 14,
fontWeight: FontWeight.normal,
color: AppColor.colorContentEmail)),
const SizedBox(height: 8), const SizedBox(height: 8),
DropdownButtonHideUnderline( DropdownButtonHideUnderline(
child: DropdownButton2<EmailAddress>( child: DropdownButton2<EmailAddress>(
isExpanded: true, isExpanded: true,
hint: Row( hint: Row(
children: [ children: const [
Expanded(child: Text( Expanded(child: Text(
_emailAddressSelected?.email ?? '', '',
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.normal, color: Colors.black), style: TextStyle(fontSize: 16, fontWeight: FontWeight.normal, color: Colors.black),
maxLines: 1, maxLines: 1,
overflow: CommonTextStyle.defaultTextOverFlow, overflow: CommonTextStyle.defaultTextOverFlow,
softWrap: CommonTextStyle.defaultSoftWrap, softWrap: CommonTextStyle.defaultSoftWrap,
@@ -51,7 +54,7 @@ class IdentityDropListFieldBuilder {
items: _listEmailAddress.map((item) => DropdownMenuItem<EmailAddress>( items: _listEmailAddress.map((item) => DropdownMenuItem<EmailAddress>(
value: item, value: item,
child: Text( child: Text(
item.email ?? '', item.emailAddress,
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.normal, color: Colors.black), style: const TextStyle(fontSize: 16, fontWeight: FontWeight.normal, color: Colors.black),
maxLines: 1, maxLines: 1,
overflow: CommonTextStyle.defaultTextOverFlow, overflow: CommonTextStyle.defaultTextOverFlow,
@@ -59,24 +62,35 @@ class IdentityDropListFieldBuilder {
), ),
)).toList(), )).toList(),
value: _emailAddressSelected, value: _emailAddressSelected,
onChanged: (newEmailAddress) => onSelectItemDropList?.call(newEmailAddress), onChanged: onSelectItemDropList,
icon: SvgPicture.asset(_imagePaths.icDropDown), buttonStyleData: ButtonStyleData(
buttonPadding: const EdgeInsets.symmetric(horizontal: 12), height: 44,
buttonDecoration: BoxDecoration( padding: const EdgeInsets.only(right: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
border: Border.all(color: AppColor.colorInputBorderCreateMailbox, width: 0.5), border: Border.all(color: AppColor.colorInputBorderCreateMailbox, width: 0.5),
color: AppColor.colorInputBackgroundCreateMailbox), color: AppColor.colorInputBackgroundCreateMailbox),
itemHeight: 44, ),
buttonHeight: 44, dropdownStyleData: DropdownStyleData(
selectedItemHighlightColor: Colors.black12, maxHeight: 200,
itemPadding: const EdgeInsets.symmetric(horizontal: 12), decoration: BoxDecoration(
dropdownMaxHeight: 200,
dropdownDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
color: Colors.white), color: Colors.white),
dropdownElevation: 4, elevation: 4,
scrollbarRadius: const Radius.circular(40), scrollbarTheme: ScrollbarThemeData(
scrollbarThickness: 6, radius: const Radius.circular(40),
thickness: MaterialStateProperty.all<double>(6),
thumbVisibility: MaterialStateProperty.all<bool>(true),
),
),
iconStyleData: IconStyleData(
icon: SvgPicture.asset(_imagePaths.icDropDown),
iconSize: 14,
),
menuItemStyleData: const MenuItemStyleData(
height: 44,
padding: EdgeInsets.symmetric(horizontal: 12),
),
), ),
) )
]); ]);
@@ -1,40 +1,49 @@
import 'package:core/core.dart'; import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/style_utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
class IdentityFieldNoEditableBuilder { class IdentityFieldNoEditableBuilder extends StatelessWidget {
final String _label; final String _label;
final EmailAddress? _emailAddressSelected; final EmailAddress? _emailAddressSelected;
IdentityFieldNoEditableBuilder(this._label, this._emailAddressSelected); const IdentityFieldNoEditableBuilder(
this._label,
this._emailAddressSelected,
{super.key}
);
Widget build() { @override
Widget build(BuildContext context) {
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(_label, style: const TextStyle( Text(
fontSize: 14, _label,
fontWeight: FontWeight.normal, style: const TextStyle(
color: AppColor.colorContentEmail)), fontSize: 14,
fontWeight: FontWeight.normal,
color: AppColor.colorContentEmail)),
const SizedBox(height: 8), const SizedBox(height: 8),
Container( Container(
height: 44, height: 44,
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 12), padding: const EdgeInsets.symmetric(horizontal: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
border: Border.all(color: AppColor.colorInputBorderCreateMailbox, width: 0.5), border: Border.all(color: AppColor.colorInputBorderCreateMailbox, width: 0.5),
color: AppColor.colorInputBackgroundCreateMailbox), color: AppColor.colorInputBackgroundCreateMailbox),
child: Text( child: Text(
_emailAddressSelected?.email ?? '', _emailAddressSelected?.email ?? '',
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
color: AppColor.colorInputBorderCreateMailbox), color: AppColor.colorInputBorderCreateMailbox),
maxLines: 1, maxLines: 1,
overflow: BuildUtils.isWeb ? null : TextOverflow.ellipsis, overflow: CommonTextStyle.defaultTextOverFlow,
) softWrap: CommonTextStyle.defaultSoftWrap
)
), ),
]); ]);
} }
@@ -1,11 +1,13 @@
import 'package:core/core.dart'; import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/views/text/text_field_builder.dart';
import 'package:core/utils/build_utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_input_decoration_builder.dart'; import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_input_decoration_builder.dart';
typedef OnChangeInputNameAction = Function(String? value); typedef OnChangeInputNameAction = Function(String? value);
class IdentityInputFieldBuilder { class IdentityInputFieldBuilder extends StatelessWidget {
final String _label; final String _label;
final String? _error; final String? _error;
@@ -14,24 +16,22 @@ class IdentityInputFieldBuilder {
final FocusNode? focusNode; final FocusNode? focusNode;
final TextInputType? inputType; final TextInputType? inputType;
final bool isMandatory; final bool isMandatory;
final OnChangeInputNameAction? onChangeInputNameAction;
OnChangeInputNameAction? onChangeInputNameAction; const IdentityInputFieldBuilder(
IdentityInputFieldBuilder(
this._label, this._label,
this._error, this._error,
this.requiredIndicator, { this.requiredIndicator, {
super.key,
this.isMandatory = false, this.isMandatory = false,
this.editingController, this.editingController,
this.focusNode, this.focusNode,
this.inputType this.inputType,
this.onChangeInputNameAction
}); });
void addOnChangeInputNameAction(OnChangeInputNameAction action) { @override
onChangeInputNameAction = action; Widget build(BuildContext context) {
}
Widget build() {
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text( Text(
isMandatory isMandatory
@@ -9,44 +9,36 @@ typedef OnSelectedSuggestionAction = Function(EmailAddress? emailAddress);
typedef OnSuggestionCallbackAction = Function(String? pattern); typedef OnSuggestionCallbackAction = Function(String? pattern);
typedef OnChangeInputSuggestionAction = Function(String? pattern); typedef OnChangeInputSuggestionAction = Function(String? pattern);
class IdentityInputWithDropListFieldBuilder { class IdentityInputWithDropListFieldBuilder extends StatelessWidget {
final String _label; final String _label;
final String? _error; final String? _error;
final TextEditingController? editingController; final TextEditingController? editingController;
final FocusNode? focusNode; final FocusNode? focusNode;
final OnSelectedSuggestionAction? onSelectedSuggestionAction;
final OnSuggestionCallbackAction? onSuggestionCallbackAction;
final OnChangeInputSuggestionAction? onChangeInputSuggestionAction;
OnSelectedSuggestionAction? _onSelectedSuggestionAction; const IdentityInputWithDropListFieldBuilder(
OnSuggestionCallbackAction? _onSuggestionCallbackAction;
OnChangeInputSuggestionAction? _onChangeInputSuggestionAction;
IdentityInputWithDropListFieldBuilder(
this._label, this._label,
this._error, this._error,
this.editingController, this.editingController, {
{ super.key,
this.focusNode, this.focusNode,
} this.onSelectedSuggestionAction,
); this.onSuggestionCallbackAction,
this.onChangeInputSuggestionAction,
});
void addOnSelectedSuggestionAction(OnSelectedSuggestionAction action) { @override
_onSelectedSuggestionAction = action; Widget build(BuildContext context) {
}
void addOnSuggestionCallbackAction(OnSuggestionCallbackAction action) {
_onSuggestionCallbackAction = action;
}
void addOnChangeInputSuggestionAction(OnChangeInputSuggestionAction action) {
_onChangeInputSuggestionAction = action;
}
Widget build() {
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(_label, style: const TextStyle( Text(
fontSize: 14, _label,
fontWeight: FontWeight.normal, style: const TextStyle(
color: AppColor.colorContentEmail)), fontSize: 14,
fontWeight: FontWeight.normal,
color: AppColor.colorContentEmail)),
const SizedBox(height: 8), const SizedBox(height: 8),
TypeAheadFormField<EmailAddress>( TypeAheadFormField<EmailAddress>(
textFieldConfiguration: TextFieldConfiguration( textFieldConfiguration: TextFieldConfiguration(
@@ -55,18 +47,18 @@ class IdentityInputWithDropListFieldBuilder {
textInputAction: TextInputAction.done, textInputAction: TextInputAction.done,
decoration: (IdentityInputDecorationBuilder() decoration: (IdentityInputDecorationBuilder()
..setContentPadding(const EdgeInsets.symmetric( ..setContentPadding(const EdgeInsets.symmetric(
vertical: BuildUtils.isWeb ? 16 : 12, vertical: BuildUtils.isWeb ? 16 : 12,
horizontal: 12)) horizontal: 12))
..setErrorText(_error)) ..setErrorText(_error))
.build() .build()
), ),
debounceDuration: const Duration(milliseconds: 500), debounceDuration: const Duration(milliseconds: 500),
suggestionsCallback: (pattern) async { suggestionsCallback: (pattern) async {
if (_onChangeInputSuggestionAction != null) { if (onChangeInputSuggestionAction != null) {
_onChangeInputSuggestionAction!(pattern); onChangeInputSuggestionAction!(pattern);
} }
if (_onSuggestionCallbackAction != null) { if (onSuggestionCallbackAction != null) {
return _onSuggestionCallbackAction!(pattern); return onSuggestionCallbackAction!(pattern);
} else { } else {
return []; return [];
} }
@@ -74,16 +66,16 @@ class IdentityInputWithDropListFieldBuilder {
itemBuilder: (BuildContext context, emailAddress) { itemBuilder: (BuildContext context, emailAddress) {
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
child: Text(emailAddress.email ?? '', child: Text(
emailAddress.email ?? '',
style: const TextStyle( style: const TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
color: Colors.black)), color: Colors.black)));
);
}, },
onSuggestionSelected: (emailSelected) { onSuggestionSelected: (emailSelected) {
if (_onSelectedSuggestionAction != null) { if (onSelectedSuggestionAction != null) {
_onSelectedSuggestionAction!(emailSelected); onSelectedSuggestionAction!(emailSelected);
} }
}, },
suggestionsBoxDecoration: SuggestionsBoxDecoration( suggestionsBoxDecoration: SuggestionsBoxDecoration(
@@ -65,29 +65,36 @@ class DateDropDownButton extends StatelessWidget {
onReceiveTimeSelected?.call(value); onReceiveTimeSelected?.call(value);
} }
}, },
icon: SvgPicture.asset(imagePaths.icDropDown), buttonStyleData: ButtonStyleData(
buttonPadding: const EdgeInsets.symmetric(horizontal: 12), height: 44,
buttonDecoration: BoxDecoration( padding: const EdgeInsets.symmetric(horizontal: 12),
borderRadius: BorderRadius.circular(10), decoration: BoxDecoration(
border: Border.all( borderRadius: BorderRadius.circular(10),
color: AppColor.colorInputBorderCreateMailbox, border: Border.all(
width: 1, color: AppColor.colorInputBorderCreateMailbox,
width: 1),
color: AppColor.colorInputBackgroundCreateMailbox)
),
dropdownStyleData: DropdownStyleData(
maxHeight: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white),
elevation: 4,
offset: const Offset(0.0, -8.0),
scrollbarTheme: ScrollbarThemeData(
radius: const Radius.circular(40),
thickness: MaterialStateProperty.all<double>(6),
thumbVisibility: MaterialStateProperty.all<bool>(true),
), ),
color: AppColor.colorInputBackgroundCreateMailbox,
), ),
itemHeight: 44, iconStyleData: IconStyleData(
buttonHeight: 44, icon: SvgPicture.asset(imagePaths.icDropDown),
selectedItemHighlightColor: Colors.white,
itemPadding: const EdgeInsets.symmetric(horizontal: 12),
dropdownMaxHeight: 200,
dropdownDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
), ),
offset: const Offset(0.0, -8.0), menuItemStyleData: const MenuItemStyleData(
dropdownElevation: 4, height: 44,
scrollbarRadius: const Radius.circular(40), padding: EdgeInsets.symmetric(horizontal: 12),
scrollbarThickness: 6 )
), ),
), ),
); );
+3 -3
View File
@@ -356,10 +356,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: dropdown_button2 name: dropdown_button2
sha256: "604b87283e251e0e4a0cb1d0fdfa91fd527702b06e80999c4054cecc603e10e7" sha256: "4458d81bfd24207f3d58f66f78097064e02f810f94cf1bc80bf20fe7685ebc80"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.4" version: "2.0.0"
enough_html_editor: enough_html_editor:
dependency: transitive dependency: transitive
description: description:
@@ -616,7 +616,7 @@ packages:
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
flutter_keyboard_visibility: flutter_keyboard_visibility:
dependency: transitive dependency: "direct main"
description: description:
name: flutter_keyboard_visibility name: flutter_keyboard_visibility
sha256: "86b71bbaffa38e885f5c21b1182408b9be6951fd125432cf6652c636254cef2d" sha256: "86b71bbaffa38e885f5c21b1182408b9be6951fd125432cf6652c636254cef2d"
+3 -1
View File
@@ -141,7 +141,7 @@ dependencies:
package_info_plus: 3.0.3 package_info_plus: 3.0.3
dropdown_button2: 1.9.4 dropdown_button2: 2.0.0
flutter_staggered_grid_view: 0.6.2 flutter_staggered_grid_view: 0.6.2
@@ -195,6 +195,8 @@ dependencies:
super_tag_editor: 0.1.1 super_tag_editor: 0.1.1
flutter_keyboard_visibility: 5.4.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter