From e7b30506189f4a13b81607fbf69be31ec96dcfe8 Mon Sep 17 00:00:00 2001 From: Prajapati Chintan Date: Fri, 13 Jan 2023 20:02:29 +0530 Subject: [PATCH] Added: VaahExtendFlutter Text Inputs --- .../helpers/input_formatters.dart | 0 .../widgets/atoms/inputs.dart | 150 ++++++++++++++++++ .../pages/ui/components/inputs/defaults.dart | 34 ++++ .../pages/ui/components/inputs/icons.dart | 59 +++++++ .../pages/ui/components/inputs/inputs.dart | 73 +++++++++ .../pages/ui/components/inputs/sizes.dart | 25 +++ lib/views/pages/ui/index.dart | 3 + 7 files changed, 344 insertions(+) create mode 100644 lib/vaahextendflutter/helpers/input_formatters.dart create mode 100644 lib/vaahextendflutter/widgets/atoms/inputs.dart create mode 100644 lib/views/pages/ui/components/inputs/defaults.dart create mode 100644 lib/views/pages/ui/components/inputs/icons.dart create mode 100644 lib/views/pages/ui/components/inputs/inputs.dart create mode 100644 lib/views/pages/ui/components/inputs/sizes.dart diff --git a/lib/vaahextendflutter/helpers/input_formatters.dart b/lib/vaahextendflutter/helpers/input_formatters.dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/vaahextendflutter/widgets/atoms/inputs.dart b/lib/vaahextendflutter/widgets/atoms/inputs.dart new file mode 100644 index 00000000..5d19c82a --- /dev/null +++ b/lib/vaahextendflutter/widgets/atoms/inputs.dart @@ -0,0 +1,150 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:team/vaahextendflutter/app_theme.dart'; +import 'package:team/vaahextendflutter/helpers/constants.dart'; + +enum InputSize { extraSmall, small, medium, large, extraLarge } + +class TextInput extends StatelessWidget { + final String? label; + final EdgeInsets padding; + final double borderRadius; + final bool isEnabled; + final InputSize size; + final TextEditingController? controller; + final Function(String)? onChanged; + final String? Function(String?)? validator; + final AutovalidateMode? autoValidateMode; + final TextInputType? keyboardType; + final List? inputFormatters; + final IconData? prefixIcon; + final Color? prefixIconColor; + final Function()? prefixOnTap; + final IconData? suffixIcon; + final Color? suffixIconColor; + final Function()? suffixOnTap; + final int? minLines; + final int? maxLines; + + const TextInput({ + super.key, + this.label, + this.padding = allPadding12, + this.borderRadius = defaultPadding / 2, + this.isEnabled = true, + this.size = InputSize.medium, + this.controller, + this.onChanged, + this.autoValidateMode, + this.validator, + this.keyboardType, + this.inputFormatters, + this.prefixIcon, + this.prefixIconColor, + this.prefixOnTap, + this.suffixIcon, + this.suffixIconColor, + this.suffixOnTap, + this.minLines, + this.maxLines, + }); + + @override + Widget build(BuildContext context) { + return TextFormField( + decoration: InputDecoration( + contentPadding: padding, + border: border(AppTheme.colors['black']!.shade400), + enabledBorder: border(AppTheme.colors['black']!.shade400), + disabledBorder: border(AppTheme.colors['black']!.shade300), + focusedBorder: border(AppTheme.colors['black']!.shade400), + errorBorder: border(AppTheme.colors['danger']!.shade400), + focusedErrorBorder: border(AppTheme.colors['danger']!.shade400), + errorStyle: TextStyle(color: AppTheme.colors['danger']!.shade400), + hintText: label, + hintStyle: TextStyle( + fontSize: getFontSize(), + color: + isEnabled ? AppTheme.colors['black']!.shade400 : AppTheme.colors['black']!.shade300, + ), + prefixIcon: prefixIcon != null + ? InkWell( + onTap: prefixOnTap, + child: Center( + child: Container( + margin: horizontalPadding4, + child: FaIcon( + prefixIcon, + size: getFontSize() * 1.15, + color: prefixIconColor ?? AppTheme.colors['black']!.shade400, + ), + ), + ), + ) + : null, + prefixIconConstraints: BoxConstraints( + maxWidth: getFontSize() * 2.3, + maxHeight: getFontSize() * 2.3, + ), + suffixIcon: suffixIcon != null + ? InkWell( + onTap: suffixOnTap, + child: Center( + child: Container( + margin: horizontalPadding4, + child: FaIcon( + suffixIcon, + size: getFontSize() * 1.15, + color: suffixIconColor ?? AppTheme.colors['black']!.shade400, + ), + ), + ), + ) + : null, + suffixIconConstraints: BoxConstraints( + maxWidth: getFontSize() * 2.3, + maxHeight: getFontSize() * 2.3, + ), + ), + keyboardType: keyboardType, + inputFormatters: inputFormatters, + validator: validator, + controller: controller, + onChanged: onChanged, + style: TextStyle( + fontSize: getFontSize(), + color: AppTheme.colors['black']!.shade400, + ), + enabled: isEnabled, + autovalidateMode: autoValidateMode, + minLines: minLines, + maxLines: maxLines, + ); + } + + OutlineInputBorder border(Color color) { + return OutlineInputBorder( + borderRadius: BorderRadius.circular(borderRadius), + borderSide: BorderSide( + width: 1, + color: color, + ), + ); + } + + double getFontSize() { + switch (size) { + case InputSize.extraSmall: + return AppTheme.extraSmall; + case InputSize.small: + return AppTheme.small; + case InputSize.large: + return AppTheme.large; + case InputSize.extraLarge: + return AppTheme.extraLarge; + default: + return AppTheme.medium; + } + } +} diff --git a/lib/views/pages/ui/components/inputs/defaults.dart b/lib/views/pages/ui/components/inputs/defaults.dart new file mode 100644 index 00000000..ba53e230 --- /dev/null +++ b/lib/views/pages/ui/components/inputs/defaults.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; +import 'package:team/vaahextendflutter/helpers/constants.dart'; +import 'package:team/vaahextendflutter/widgets/atoms/inputs.dart'; +import 'package:team/views/pages/ui/components/commons.dart'; + +class DefaultTextInputs extends StatelessWidget { + const DefaultTextInputs({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final GlobalKey formKey = GlobalKey(); + return Form( + key: formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Defaults', style: heading), + verticalMargin16, + const TextInput(label: 'Default'), + verticalMargin8, + const TextInput(label: 'Disabled', isEnabled: false), + verticalMargin8, + TextInput(label: 'Invalid', validator: (_) => 'Message'), + verticalMargin8, + ElevatedButton( + onPressed: () => formKey.currentState?.validate(), + child: const Text('Submit'), + ), + ], + ), + ); + } +} diff --git a/lib/views/pages/ui/components/inputs/icons.dart b/lib/views/pages/ui/components/inputs/icons.dart new file mode 100644 index 00000000..f5cfeedb --- /dev/null +++ b/lib/views/pages/ui/components/inputs/icons.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:team/vaahextendflutter/app_theme.dart'; +import 'package:team/vaahextendflutter/helpers/alerts.dart'; +import 'package:team/vaahextendflutter/helpers/constants.dart'; +import 'package:team/vaahextendflutter/widgets/atoms/inputs.dart'; +import 'package:team/views/pages/ui/components/commons.dart'; + +class InputIcons extends StatelessWidget { + const InputIcons({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Input Icons', style: heading), + verticalMargin16, + const TextInput( + size: InputSize.small, + label: 'Small', + prefixIcon: FontAwesomeIcons.user, + ), + verticalMargin8, + const TextInput( + size: InputSize.medium, + label: 'Medium', + prefixIcon: FontAwesomeIcons.user, + ), + verticalMargin8, + const TextInput( + size: InputSize.large, + label: 'Large', + prefixIcon: FontAwesomeIcons.user, + ), + verticalMargin8, + const TextInput( + label: 'Search', + suffixIcon: FontAwesomeIcons.magnifyingGlass, + ), + verticalMargin8, + TextInput( + label: 'Search', + prefixOnTap: () { + Alerts.showSuccessToast!(content: 'Prefix icon onTap'); + }, + suffixOnTap: () { + Alerts.showErrorToast!(content: 'Suffix icon onTap'); + }, + prefixIcon: FontAwesomeIcons.user, + prefixIconColor: AppTheme.colors['primary'], + suffixIcon: FontAwesomeIcons.magnifyingGlass, + suffixIconColor: AppTheme.colors['primary'], + ), + ], + ); + } +} diff --git a/lib/views/pages/ui/components/inputs/inputs.dart b/lib/views/pages/ui/components/inputs/inputs.dart new file mode 100644 index 00000000..df5a3928 --- /dev/null +++ b/lib/views/pages/ui/components/inputs/inputs.dart @@ -0,0 +1,73 @@ +import 'package:flutter/material.dart'; +import 'package:team/vaahextendflutter/app_theme.dart'; +import 'package:team/vaahextendflutter/helpers/constants.dart'; +import 'package:team/vaahextendflutter/helpers/styles.dart'; +import 'package:team/vaahextendflutter/widgets/atoms/container_with_rounded_border.dart'; +import 'package:team/views/pages/ui/components/inputs/defaults.dart'; +import 'package:team/views/pages/ui/components/inputs/icons.dart'; +import 'package:team/views/pages/ui/components/inputs/sizes.dart'; +import 'package:team/views/pages/ui/components/section_title_selector.dart'; + +class AppInputs extends StatefulWidget { + const AppInputs({Key? key}) : super(key: key); + + @override + State createState() => _AppInputsState(); +} + +class _AppInputsState extends State { + int _selectedIndex = 0; + + @override + Widget build(BuildContext context) { + return ContainerWithRoundedBorder( + width: double.infinity, + color: AppTheme.colors['white']!, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Text Inputs', style: TextStyles.semiBold7), + verticalMargin24, + tabOptions(), + Divider(color: AppTheme.colors['primary']!.shade200), + verticalMargin24, + const DefaultTextInputs(), + verticalMargin24, + const InputSizes(), + verticalMargin24, + const InputIcons(), + verticalMargin24, + ], + ), + ); + } + + Widget tabOptions() { + return Wrap( + crossAxisAlignment: WrapCrossAlignment.end, + children: [ + sectionTitleSelector( + title: 'Preview', + condition: _selectedIndex == 0, + callback: () { + setState(() { + _selectedIndex = 0; + }); + }, + ), + verticalMargin12, + horizontalMargin12, + sectionTitleSelector( + title: 'Code', + condition: _selectedIndex == 1, + callback: () { + setState(() { + _selectedIndex = 1; + }); + }, + ), + ], + ); + } +} diff --git a/lib/views/pages/ui/components/inputs/sizes.dart b/lib/views/pages/ui/components/inputs/sizes.dart new file mode 100644 index 00000000..3fab3c52 --- /dev/null +++ b/lib/views/pages/ui/components/inputs/sizes.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:team/vaahextendflutter/helpers/constants.dart'; +import 'package:team/vaahextendflutter/widgets/atoms/inputs.dart'; +import 'package:team/views/pages/ui/components/commons.dart'; + +class InputSizes extends StatelessWidget { + const InputSizes({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Input Sizes', style: heading), + verticalMargin16, + const TextInput(size: InputSize.small, label: 'Small'), + verticalMargin8, + const TextInput(size: InputSize.medium, label: 'Medium'), + verticalMargin8, + const TextInput(size: InputSize.large, label: 'Large'), + ], + ); + } +} diff --git a/lib/views/pages/ui/index.dart b/lib/views/pages/ui/index.dart index df60167b..7ac3fe31 100644 --- a/lib/views/pages/ui/index.dart +++ b/lib/views/pages/ui/index.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:team/vaahextendflutter/app_theme.dart'; import 'package:team/vaahextendflutter/base/base_stateful.dart'; import 'package:team/vaahextendflutter/helpers/constants.dart'; +import 'package:team/views/pages/ui/components/inputs/inputs.dart'; import 'package:team/views/pages/ui/components/themecolors.dart'; class UIPage extends StatefulWidget { @@ -39,6 +40,8 @@ class _UIPageState extends BaseStateful { verticalMargin24, AppThemeColors(), verticalMargin24, + AppInputs(), + verticalMargin24, ], ), ),