TF-4229 refactor(ui): optimize LabelDropDownButton widget structure and rebuild scope

This commit is contained in:
dab246
2026-01-06 00:24:54 +07:00
committed by Dat H. Pham
parent cc508c210a
commit 87341d7052
@@ -3,7 +3,8 @@ import 'package:core/presentation/resources/image_paths.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:labels/labels.dart'; import 'package:labels/extensions/label_extension.dart';
import 'package:labels/model/label.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/styles/advanced_search_input_form_style.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/styles/advanced_search_input_form_style.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/styles/label_drop_down_style.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/styles/label_drop_down_style.dart';
@@ -17,13 +18,13 @@ class LabelDropDownButton extends StatelessWidget {
final Label? labelSelected; final Label? labelSelected;
final OnSelectLabelsActions onSelectLabelsActions; final OnSelectLabelsActions onSelectLabelsActions;
const LabelDropDownButton({ LabelDropDownButton({
Key? key, super.key,
required this.imagePaths, required this.imagePaths,
required this.labels, required this.labels,
required this.labelSelected, required this.labelSelected,
required this.onSelectLabelsActions, required this.onSelectLabelsActions,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -31,67 +32,112 @@ class LabelDropDownButton extends StatelessWidget {
child: PointerInterceptor( child: PointerInterceptor(
child: DropdownButton2<Label>( child: DropdownButton2<Label>(
isExpanded: true, isExpanded: true,
items: labels.map((label) {
final isSelected = labelSelected?.id == label.id;
return DropdownMenuItem<Label>(
value: label,
child: PointerInterceptor(
child: Row(
spacing: 16,
children: [
SvgPicture.asset(
isSelected
? imagePaths.icCheckboxSelected
: imagePaths.icCheckboxUnselected,
width: LabelDropDownStyle.checkedIconSize,
height: LabelDropDownStyle.checkedIconSize,
colorFilter: isSelected
? LabelDropDownStyle.checkedIconColor.asFilter()
: LabelDropDownStyle.unCheckedIconColor.asFilter(),
fit: BoxFit.fill,
),
Expanded(
child: Text(
label.safeDisplayName,
style: LabelDropDownStyle.menuItemStyle,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
);
}).toList(),
value: labelSelected, value: labelSelected,
customButton: _buildButton(AppLocalizations.of(context)), items: _buildItems(),
onChanged: onSelectLabelsActions, customButton: _LabelDropdownButtonView(
dropdownStyleData: DropdownStyleData( imagePaths: imagePaths,
maxHeight: LabelDropDownStyle.dropdownMaxHeight, labelSelected: labelSelected,
decoration: LabelDropDownStyle.dropdownDecoration, localizations: AppLocalizations.of(context),
elevation: LabelDropDownStyle.dropdownElevation,
offset: LabelDropDownStyle.dropdownOffset,
padding: LabelDropDownStyle.dropdownPadding,
scrollbarTheme: ScrollbarThemeData(
radius: LabelDropDownStyle.dropdownScrollbarRadius,
thickness: WidgetStateProperty.all<double>(
LabelDropDownStyle.scrollbarThickness,
),
thumbVisibility: WidgetStateProperty.all<bool>(true),
),
), ),
onChanged: onSelectLabelsActions,
dropdownStyleData: _dropdownStyleData,
menuItemStyleData: LabelDropDownStyle.menuItemStyleData, menuItemStyleData: LabelDropDownStyle.menuItemStyleData,
), ),
), ),
); );
} }
Widget _buildButton(AppLocalizations appLocalizations) { List<DropdownMenuItem<Label>> _buildItems() {
return labels.map((label) {
return DropdownMenuItem<Label>(
value: label,
child: _LabelDropdownMenuItem(
label: label,
isSelected: labelSelected?.id == label.id,
imagePaths: imagePaths,
),
);
}).toList(growable: false);
}
final DropdownStyleData _dropdownStyleData = DropdownStyleData(
maxHeight: LabelDropDownStyle.dropdownMaxHeight,
decoration: LabelDropDownStyle.dropdownDecoration,
elevation: LabelDropDownStyle.dropdownElevation,
offset: LabelDropDownStyle.dropdownOffset,
padding: LabelDropDownStyle.dropdownPadding,
scrollbarTheme: ScrollbarThemeData(
radius: LabelDropDownStyle.dropdownScrollbarRadius,
thickness: WidgetStateProperty.all<double>(
LabelDropDownStyle.scrollbarThickness,
),
thumbVisibility: WidgetStateProperty.all<bool>(true),
),
);
}
class _LabelDropdownMenuItem extends StatelessWidget {
final Label label;
final bool isSelected;
final ImagePaths imagePaths;
const _LabelDropdownMenuItem({
required this.label,
required this.isSelected,
required this.imagePaths,
});
@override
Widget build(BuildContext context) {
return PointerInterceptor(
child: Row(
spacing: 16,
children: [
SvgPicture.asset(
isSelected
? imagePaths.icCheckboxSelected
: imagePaths.icCheckboxUnselected,
width: LabelDropDownStyle.checkedIconSize,
height: LabelDropDownStyle.checkedIconSize,
colorFilter: (isSelected
? LabelDropDownStyle.checkedIconColor
: LabelDropDownStyle.unCheckedIconColor)
.asFilter(),
fit: BoxFit.fill,
),
Expanded(
child: Text(
label.safeDisplayName,
style: LabelDropDownStyle.menuItemStyle,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
);
}
}
class _LabelDropdownButtonView extends StatelessWidget {
final ImagePaths imagePaths;
final Label? labelSelected;
final AppLocalizations localizations;
const _LabelDropdownButtonView({
required this.imagePaths,
required this.labelSelected,
required this.localizations,
});
@override
Widget build(BuildContext context) {
final displayedName = final displayedName =
labelSelected?.safeDisplayName ?? appLocalizations.allLabels; labelSelected?.safeDisplayName ?? localizations.allLabels;
return Container( return Container(
height: AdvancedSearchInputFormStyle.inputFieldHeight, height: AdvancedSearchInputFormStyle.inputFieldHeight,
padding: LabelDropDownStyle.buttonPadding,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: const BorderRadius.all( borderRadius: const BorderRadius.all(
Radius.circular( Radius.circular(
@@ -104,7 +150,6 @@ class LabelDropDownButton extends StatelessWidget {
), ),
color: AdvancedSearchInputFormStyle.inputFieldBackgroundColor, color: AdvancedSearchInputFormStyle.inputFieldBackgroundColor,
), ),
padding: LabelDropDownStyle.buttonPadding,
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(
@@ -115,7 +160,7 @@ class LabelDropDownButton extends StatelessWidget {
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
), ),
SvgPicture.asset(imagePaths.icDropDown) SvgPicture.asset(imagePaths.icDropDown),
], ],
), ),
); );