TF-3763 Update style for Has attachment checkbox in advanced search view

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-06-13 11:20:15 +07:00
committed by Dat H. Pham
parent 061f5d232c
commit c528722685
7 changed files with 134 additions and 78 deletions
+2
View File
@@ -93,6 +93,8 @@ export 'presentation/views/toast/toast_position.dart';
export 'presentation/views/toast/tmail_toast.dart'; export 'presentation/views/toast/tmail_toast.dart';
export 'presentation/views/bottom_popup/full_screen_action_sheet_builder.dart'; export 'presentation/views/bottom_popup/full_screen_action_sheet_builder.dart';
export 'presentation/views/checkbox/labeled_checkbox.dart'; export 'presentation/views/checkbox/labeled_checkbox.dart';
export 'presentation/views/checkbox/default_labeled_checkbox.dart';
export 'presentation/views/checkbox/custom_icon_labeled_checkbox.dart';
export 'presentation/views/container/tmail_container_widget.dart'; export 'presentation/views/container/tmail_container_widget.dart';
export 'presentation/views/clipper/side_arrow_clipper.dart'; export 'presentation/views/clipper/side_arrow_clipper.dart';
export 'presentation/views/avatar/gradient_circle_avatar_icon.dart'; export 'presentation/views/avatar/gradient_circle_avatar_icon.dart';
@@ -261,6 +261,15 @@ class ThemeUtils {
color: AppColor.textPrimary, color: AppColor.textPrimary,
); );
static const TextStyle textStyleM3BodyMedium3 = TextStyle(
fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.w400,
letterSpacing: 0.25,
fontSize: 14,
height: 20 / 14,
color: AppColor.m3SurfaceBackground,
);
static TextStyle textStyleAppShortcut() => const TextStyle( static TextStyle textStyleAppShortcut() => const TextStyle(
fontFamily: ConstantsUI.fontApp, fontFamily: ConstantsUI.fontApp,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
@@ -0,0 +1,44 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/views/checkbox/labeled_checkbox.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class CustomIconLabeledCheckbox extends LabeledCheckbox {
final String svgIconPath;
final String selectedSvgIconPath;
final FocusNode focusNode;
const CustomIconLabeledCheckbox({
super.key,
required super.label,
required super.onChanged,
required this.svgIconPath,
required this.selectedSvgIconPath,
required this.focusNode,
super.value,
super.gap = 16.0,
});
@override
Widget get buildCheckboxWidget => FocusableActionDetector(
focusNode: focusNode,
autofocus: false,
child: Material(
type: MaterialType.transparency,
child: InkWell(
canRequestFocus: true,
focusColor: AppColor.colorMailboxHovered,
borderRadius: const BorderRadius.all(Radius.circular(20)),
onTap: () => onChanged(!(value)),
child: SvgPicture.asset(
value ? selectedSvgIconPath : svgIconPath,
width: 20,
height: 20,
colorFilter: AppColor.primaryColor.asFilter(),
fit: BoxFit.fill,
),
),
),
);
}
@@ -0,0 +1,28 @@
import 'package:core/presentation/views/checkbox/labeled_checkbox.dart';
import 'package:flutter/material.dart';
class DefaultLabeledCheckbox extends LabeledCheckbox {
final Color activeColor;
final FocusNode focusNode;
const DefaultLabeledCheckbox({
super.key,
required super.label,
required super.onChanged,
required this.activeColor,
required this.focusNode,
super.value,
super.gap,
super.textStyle,
});
@override
Widget get buildCheckboxWidget => Checkbox(
value: value,
activeColor: activeColor,
visualDensity: VisualDensity.compact,
focusNode: focusNode,
onChanged: onChanged,
);
}
@@ -1,60 +1,49 @@
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
typedef OnChangedAction = void Function(bool? value);
class LabeledCheckbox extends StatelessWidget { class LabeledCheckbox extends StatelessWidget {
const LabeledCheckbox({Key? key, const LabeledCheckbox({
Key? key,
required this.label, required this.label,
this.contentPadding, required this.onChanged,
this.value, this.value = false,
this.onChanged,
this.activeColor,
this.fontSize = 16,
this.gap = 4.0, this.gap = 4.0,
this.bold = false, this.textStyle,
this.focusNode,
}) : super(key: key); }) : super(key: key);
final String label; final String label;
final EdgeInsets? contentPadding; final bool value;
final bool? value; final OnChangedAction onChanged;
final Function(bool?)? onChanged;
final Color? activeColor;
final double fontSize;
final double gap; final double gap;
final bool bold; final TextStyle? textStyle;
final FocusNode? focusNode;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return InkWell( return InkWell(
onTap: () => onChanged?.call(!(value ?? false)), onTap: () => onChanged(!(value)),
child: Padding( child: Row(
padding: contentPadding ?? const EdgeInsets.all(0), mainAxisSize: MainAxisSize.min,
child: Row( children: <Widget>[
mainAxisSize: MainAxisSize.min, buildCheckboxWidget,
children: <Widget>[ buildGapWidget,
Checkbox( buildLabelWidget,
value: value, ],
activeColor: activeColor,
visualDensity: VisualDensity.compact,
focusNode: focusNode,
onChanged: onChanged,
),
SizedBox(
width: gap,
),
Flexible(
child: Text(
label,
style: TextStyle(
fontSize: fontSize,
fontWeight: bold ? FontWeight.bold : FontWeight.normal,
color: Colors.black
),
),
),
],
),
), ),
); );
} }
Widget get buildCheckboxWidget => Checkbox(
value: value,
visualDensity: VisualDensity.compact,
onChanged: onChanged,
);
Widget get buildGapWidget => SizedBox(width: gap);
Widget get buildLabelWidget => Text(
label,
style: textStyle ?? ThemeUtils.textStyleM3BodyMedium3,
);
} }
@@ -1,5 +1,5 @@
import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/views/checkbox/labeled_checkbox.dart'; import 'package:core/presentation/views/checkbox/default_labeled_checkbox.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/base/isolate/background_isolate_binary_messenger/background_isolate_binary_messenger_mobile.dart'; import 'package:tmail_ui_user/features/base/isolate/background_isolate_binary_messenger/background_isolate_binary_messenger_mobile.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -8,16 +8,16 @@ typedef OnChangedHasAttachment = void Function(bool? value);
class CheckBoxHasAttachmentWidget extends StatelessWidget { class CheckBoxHasAttachmentWidget extends StatelessWidget {
final bool hasAttachmentValue; final bool hasAttachmentValue;
final FocusNode? currentFocusNode; final FocusNode currentFocusNode;
final FocusNode? nextFocusNode; final FocusNode? nextFocusNode;
final OnChangedHasAttachment? onChanged; final OnChangedHasAttachment onChanged;
const CheckBoxHasAttachmentWidget({ const CheckBoxHasAttachmentWidget({
super.key, super.key,
required this.hasAttachmentValue, required this.hasAttachmentValue,
this.currentFocusNode, required this.currentFocusNode,
required this.onChanged,
this.nextFocusNode, this.nextFocusNode,
this.onChanged,
}); });
@override @override
@@ -29,10 +29,9 @@ class CheckBoxHasAttachmentWidget extends StatelessWidget {
nextFocusNode?.requestFocus(); nextFocusNode?.requestFocus();
} }
}, },
child: LabeledCheckbox( child: DefaultLabeledCheckbox(
label: AppLocalizations.of(context).hasAttachment, label: AppLocalizations.of(context).hasAttachment,
focusNode: currentFocusNode, focusNode: currentFocusNode,
contentPadding: EdgeInsets.zero,
value: hasAttachmentValue, value: hasAttachmentValue,
activeColor: AppColor.primaryColor, activeColor: AppColor.primaryColor,
onChanged: onChanged, onChanged: onChanged,
@@ -1,7 +1,7 @@
import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/button/icon_button_web.dart'; import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/presentation/views/checkbox/labeled_checkbox.dart'; import 'package:core/presentation/views/checkbox/custom_icon_labeled_checkbox.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@@ -24,12 +24,9 @@ class AdvancedSearchFilterFormBottomView extends GetWidget<AdvancedFilterControl
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Transform( _buildCheckboxHasAttachment(
transform: Matrix4.translationValues(-8.0, 0.0, 0.0), context,
child: _buildCheckboxHasAttachment( focusManager.attachmentCheckboxFocusNode,
context,
currentFocusNode: focusManager.attachmentCheckboxFocusNode,
nextFocusNode: focusManager.searchButtonFocusNode),
), ),
_buildListButton(context, controller.responsiveUtils), _buildListButton(context, controller.responsiveUtils),
], ],
@@ -105,28 +102,16 @@ class AdvancedSearchFilterFormBottomView extends GetWidget<AdvancedFilterControl
Widget _buildCheckboxHasAttachment( Widget _buildCheckboxHasAttachment(
BuildContext context, BuildContext context,
{ FocusNode currentFocusNode,
FocusNode? currentFocusNode,
FocusNode? nextFocusNode,
}
) { ) {
return Obx( return Obx(
() => KeyboardListener( () => CustomIconLabeledCheckbox(
focusNode: FocusNode(), label: AppLocalizations.of(context).hasAttachment,
onKeyEvent: (event) { svgIconPath: controller.imagePaths.icCheckboxUnselected,
if (event is KeyDownEvent && selectedSvgIconPath: controller.imagePaths.icCheckboxSelected,
event.logicalKey == LogicalKeyboardKey.tab) { focusNode: currentFocusNode,
nextFocusNode?.requestFocus(); value: controller.hasAttachment.value,
} onChanged: controller.onHasAttachmentCheckboxChanged,
},
child: LabeledCheckbox(
label: AppLocalizations.of(context).hasAttachment,
focusNode: currentFocusNode,
contentPadding: EdgeInsets.zero,
value: controller.hasAttachment.value,
activeColor: AppColor.primaryColor,
onChanged: controller.onHasAttachmentCheckboxChanged,
),
), ),
); );
} }