Houshan-Basa/lib/ui/widgets/components/text/labeled_text_field.dart

171 lines
6.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hoshan/core/utils/strings.dart';
import 'package:hoshan/data/model/edittext_state_model.dart';
import 'package:hoshan/ui/theme/colors.dart';
import 'package:hoshan/ui/theme/text.dart';
import 'package:hoshan/ui/widgets/components/dropdown/hint_tooltip.dart';
import 'package:hoshan/ui/widgets/components/snackbar/snackbar_manager.dart';
class LabeledTextField extends StatefulWidget {
final EdittextStateModel? stateController;
final Function(String)? onChange;
final String? Function(String?)? onValid;
final int? maxLength;
final TextInputAction textInputAction;
final Widget? suffix;
final Widget? error;
final Widget? success;
final bool isPassword;
final bool enabled;
final int? minLines;
final int? maxLines;
final TextStyle? hintStyle;
final bool showLabel;
final bool justEnglish;
const LabeledTextField(
{super.key,
this.onChange,
this.maxLength,
this.suffix,
this.error,
this.success,
this.isPassword = false,
this.enabled = true,
this.minLines,
this.maxLines,
this.onValid,
this.stateController,
this.hintStyle,
this.textInputAction = TextInputAction.done,
this.showLabel = true,
this.justEnglish = false});
@override
State<LabeledTextField> createState() => _LabeledTextFieldState();
}
class _LabeledTextFieldState extends State<LabeledTextField> {
String text = '';
bool resetError = false;
bool isPassword = false;
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: Form(
key: widget.stateController?.formState,
child: TextFormField(
textInputAction: widget.minLines != null && widget.minLines! > 1
? TextInputAction.newline
: widget.textInputAction,
controller: widget.stateController?.formController,
onChanged: (value) {
widget.onChange?.call(value);
setState(() {
text = value;
resetError = true;
widget.stateController?.formState.currentState?.validate();
});
},
validator: (value) {
if (resetError) {
resetError = false;
return null;
}
return widget.onValid?.call(value);
},
inputFormatters: widget.justEnglish
? [
TextInputFormatter.withFunction((oldValue, newValue) {
if (!newValue.text.containsOnlyEnglish()) {
SnackBarManager(context, id: 'justTypeEnglish').show(
status: SnackBarStatus.info,
message: 'نام کاربری باید فقط شامل حروف انگلیسی باشد',
);
return oldValue;
}
return newValue;
}),
]
: null,
maxLength: widget.maxLength,
obscureText: widget.isPassword && isPassword,
style: AppTextStyles.body4
.copyWith(color: Theme.of(context).colorScheme.onSurface),
minLines: widget.minLines,
maxLines: widget.maxLines,
textDirection:
text.startsWithEnglish() ? TextDirection.ltr : TextDirection.rtl,
decoration: InputDecoration(
labelStyle: AppTextStyles.body4
.copyWith(color: AppColors.primaryColor.defaultShade),
errorStyle: AppTextStyles.body4.copyWith(
color: AppColors.red.defaultShade, fontWeight: FontWeight.bold),
hintText: widget.stateController?.hintText,
hintStyle: widget.hintStyle ?? AppTextStyles.body5,
contentPadding: const EdgeInsets.all(18),
error: widget.error ?? widget.success,
enabled: widget.enabled,
floatingLabelBehavior:
FloatingLabelBehavior.always, // Add this line
label: widget.stateController?.label != null
? Opacity(
opacity: widget.showLabel ? 1 : 0,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (widget.stateController?.tooltipHint != null)
Row(
children: [
HintTooltip(
hint: widget.stateController!.tooltipHint!),
const SizedBox(
width: 12,
),
],
),
Text(
widget.stateController?.label ?? '',
style: AppTextStyles.body2.copyWith(
color: Theme.of(context).colorScheme.primary),
),
if (!widget.showLabel)
const SizedBox(
width: 16,
),
],
),
)
: null,
fillColor: AppColors.primaryColor.defaultShade,
focusColor: AppColors.primaryColor.defaultShade,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide:
BorderSide(color: AppColors.primaryColor.defaultShade)),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: widget.success != null
? AppColors.green.defaultShade
: AppColors.red.defaultShade,
width: 2)),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: widget.success != null
? AppColors.green.defaultShade
: AppColors.red.defaultShade,
width: 2)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: AppColors.primaryColor.defaultShade, width: 2)),
),
),
),
);
}
}