Line data Source code
1 : import 'package:cwtch/cwtch_icons_icons.dart';
2 : import 'package:flutter/material.dart';
3 : import 'package:provider/provider.dart';
4 : import '../settings.dart';
5 : import 'package:flutter_gen/gen_l10n/app_localizations.dart';
6 :
7 : const hints = [AutofillHints.password];
8 :
9 : // Provides a styled Password Input Field for use in Form Widgets.
10 : // Callers must provide a text controller, label helper text and a validator.
11 : class CwtchPasswordField extends StatefulWidget {
12 0 : CwtchPasswordField({required this.controller, required this.validator, this.action, this.autofocus = false, this.autoFillHints = hints, this.key});
13 : final TextEditingController controller;
14 : final FormFieldValidator validator;
15 : final Function(String)? action;
16 : final bool autofocus;
17 : final Iterable<String> autoFillHints;
18 : final Key? key;
19 :
20 0 : @override
21 0 : _CwtchPasswordTextFieldState createState() => _CwtchPasswordTextFieldState();
22 : }
23 :
24 : class _CwtchPasswordTextFieldState extends State<CwtchPasswordField> {
25 : bool obscureText = true;
26 :
27 0 : @override
28 : void initState() {
29 0 : super.initState();
30 : }
31 :
32 0 : @override
33 : Widget build(BuildContext context) {
34 : // todo: translations
35 0 : var label = AppLocalizations.of(context)!.tooltipShowPassword;
36 0 : if (!obscureText) {
37 0 : label = AppLocalizations.of(context)!.tooltipHidePassword;
38 : }
39 :
40 0 : return Consumer<Settings>(builder: (context, theme, child) {
41 : // Horrifying Hack: Flutter doesn't give us direct control over system menus but instead picks BG color from TextButtonThemeData ¯\_(ツ)_/¯
42 0 : return Theme(
43 0 : data: Theme.of(context).copyWith(
44 0 : textButtonTheme: TextButtonThemeData(
45 0 : style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Provider.of<Settings>(context).theme.menuBackgroundColor)),
46 : ),
47 : ),
48 0 : child: TextFormField(
49 0 : autofocus: widget.autofocus,
50 0 : controller: widget.controller,
51 0 : validator: widget.validator,
52 0 : obscureText: obscureText,
53 : obscuringCharacter: '*',
54 : enableIMEPersonalizedLearning: false,
55 0 : autofillHints: widget.autoFillHints,
56 : autovalidateMode: AutovalidateMode.always,
57 0 : onFieldSubmitted: widget.action,
58 : enableSuggestions: false,
59 : autocorrect: false,
60 0 : decoration: InputDecoration(
61 0 : suffixIcon: IconButton(
62 0 : onPressed: () {
63 0 : setState(() {
64 0 : obscureText = !obscureText;
65 : });
66 : },
67 0 : icon: Icon((obscureText ? CwtchIcons.eye_closed : CwtchIcons.eye_open), semanticLabel: label),
68 : tooltip: label,
69 0 : color: theme.current().mainTextColor,
70 0 : highlightColor: theme.current().defaultButtonColor,
71 0 : focusColor: theme.current().defaultButtonActiveColor,
72 0 : splashColor: theme.current().defaultButtonActiveColor,
73 0 : splashRadius: Material.defaultSplashRadius / 2,
74 : ),
75 0 : errorStyle: TextStyle(
76 0 : color: theme.current().textfieldErrorColor,
77 : fontWeight: FontWeight.bold,
78 : ),
79 0 : focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(6.0), borderSide: BorderSide(color: theme.current().textfieldBorderColor, width: 1.0)),
80 0 : focusedErrorBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(6.0), borderSide: BorderSide(color: theme.current().textfieldErrorColor, width: 1.0)),
81 0 : errorBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(6.0), borderSide: BorderSide(color: theme.current().textfieldErrorColor, width: 1.0)),
82 : filled: true,
83 0 : fillColor: theme.current().textfieldBackgroundColor,
84 0 : enabledBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(6.0), borderSide: BorderSide(color: theme.current().textfieldBorderColor, width: 1.0)),
85 : ),
86 : ));
87 : });
88 : }
89 : }
|