TF-4178 Add create new label modal

This commit is contained in:
dab246
2025-11-26 12:10:55 +07:00
committed by Dat H. Pham
parent f6f299dc97
commit d3029ec4de
16 changed files with 629 additions and 1 deletions
+2
View File
@@ -117,6 +117,8 @@ export 'presentation/views/semantics/text_field_semantics.dart';
export 'presentation/views/semantics/icon_semantics.dart';
export 'presentation/views/shortcut/key_shortcut.dart';
export 'presentation/views/tooltip/iframe_tooltip_overlay.dart';
export 'presentation/views/color/color_circle_widget.dart';
export 'presentation/views/color/colors_map_widget.dart';
// Resources
export 'presentation/resources/assets_paths.dart';
@@ -280,6 +280,7 @@ extension AppColor on Color {
static const gray49454F = Color(0xFF49454F);
static const blue00B7FF = Color(0xFF00B7FF);
static const blueD2E9FF = Color(0xFFD2E9FF);
static const grayCDCDCD = Color(0xFFCDCDCD);
static const lightGrayF9FAFB = Color(0xFFF9FAFB);
static const black4D4D4D = Color(0xFF4D4D4D);
static const black1A1A1A = Color(0xFF1A1A1A);
@@ -276,6 +276,7 @@ class ImagePaths {
String get icAiMoreProfessional => _getImagePath('ic_ai_more_professional.svg');
String get icAiMorePolite => _getImagePath('ic_ai_more_polite.svg');
String get icTag => _getImagePath('ic_tag.svg');
String get icColorPicker => _getImagePath('ic_color_picker.svg');
String _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
@@ -110,6 +110,7 @@ class TMailButtonWidget extends StatelessWidget {
EdgeInsetsGeometry? margin,
Color? hoverColor,
Alignment? alignment,
BoxBorder? border,
}) {
return TMailButtonWidget(
key: key,
@@ -137,6 +138,7 @@ class TMailButtonWidget extends StatelessWidget {
margin: margin,
hoverColor: hoverColor,
alignment: alignment,
border: border,
);
}
@@ -0,0 +1,49 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class ColorCircleWidget extends StatelessWidget {
final Color color;
final bool isSelected;
final ImagePaths imagePaths;
final VoidCallback onTap;
const ColorCircleWidget({
super.key,
required this.color,
required this.isSelected,
required this.imagePaths,
required this.onTap,
});
@override
Widget build(BuildContext context) {
return Material(
type: MaterialType.transparency,
child: InkWell(
onTap: onTap,
customBorder: const CircleBorder(),
child: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: color,
shape: BoxShape.circle,
),
child: isSelected
? Center(
child: SvgPicture.asset(
imagePaths.icCheck,
colorFilter: Colors.white.asFilter(),
width: 18.46,
height: 18.46,
fit: BoxFit.fill,
),
)
: null,
),
),
);
}
}
@@ -0,0 +1,131 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:core/presentation/views/color/color_circle_widget.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class ColorsMapWidget extends StatefulWidget {
final Color? initialColor;
const ColorsMapWidget({
super.key,
this.initialColor,
});
@override
State<ColorsMapWidget> createState() => _ColorsMapWidgetState();
}
class _ColorsMapWidgetState extends State<ColorsMapWidget> {
static const List<Color> _defaultColors = [
Color(0xFF273891),
Color(0xFF7E57E3),
Color(0xFF9E83E8),
Color(0xFF617ADB),
Color(0xFF4896E5),
Color(0xFF038199),
Color(0xFF457D6C),
Color(0xFF1EBBCC),
Color(0xFF51B588),
Color(0xFFE0465C),
Color(0xFFED20A4),
Color(0xFFED768D),
Color(0xFFB85B17),
Color(0xFFBA8144),
Color(0xFFED916B),
Color(0xFFEDA91D),
Color(0xFFEDC661),
Color(0xFF131326),
Color(0xFF2C2C42),
Color(0xFF646580),
];
final _imagePaths = Get.find<ImagePaths>();
final ValueNotifier<Color?> _selectedColor = ValueNotifier(null);
@override
void initState() {
super.initState();
_selectedColor.value = widget.initialColor;
}
@override
Widget build(BuildContext context) {
return Wrap(
spacing: 10,
runSpacing: 10,
children: [
TMailButtonWidget.fromIcon(
icon: _imagePaths.icCloseDialog,
iconColor: AppColor.m3SurfaceBackground.withValues(alpha: 0.48),
iconSize: 18.46,
width: 40,
height: 40,
borderRadius: 100,
backgroundColor: Colors.transparent,
border: Border.all(width: 2, color: AppColor.grayCDCDCD),
onTapActionCallback: _clearColor,
),
..._defaultColors
.map(
(color) => ValueListenableBuilder(
valueListenable: _selectedColor,
builder: (context, value, child) {
return ColorCircleWidget(
color: color,
isSelected: color == value,
onTap: () => _selectColor(color),
imagePaths: _imagePaths,
);
},
),
)
.toList(),
Container(
padding: const EdgeInsets.all(2),
decoration: const BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [
Color(0xFFFB2C36),
Color(0xFFAD46FF),
Color(0xFF2B7FFF),
],
stops: [0, 0.5, 1],
begin: AlignmentDirectional.topStart,
end: AlignmentDirectional.bottomEnd,
),
),
child: TMailButtonWidget.fromIcon(
icon: _imagePaths.icColorPicker,
iconColor: AppColor.textSecondary,
iconSize: 18.46,
width: 40,
height: 40,
borderRadius: 100,
backgroundColor: Colors.white,
onTapActionCallback: _openColorPicker,
),
),
],
);
}
void _selectColor(Color color) {
_selectedColor.value = color;
}
void _clearColor() {
_selectedColor.value = null;
}
void _openColorPicker() {}
@override
void dispose() {
_selectedColor.dispose();
super.dispose();
}
}