CustomTextFormField

A highly customizable text input field with support for various input types, validation, masking, and advanced styling options.

Features

  • Multiple Input Types:
    • Text, email, password, phone, multiline
    • Custom keyboard actions
    • Input formatting/masking
  • Visual Customization:
    • Fully customizable borders (enabled/disabled/error states)
    • Prefix/suffix icons
    • Custom padding and margins
  • Functional Enhancements:
    • Autofill support
    • Password visibility toggle
    • Character counting
    • Validation handling
  • State Management:
    • Focus node control
    • Enabled/disabled states
    • Controller integration

Installation

Add the dependency to your pubspec.yaml:

dependencies:
  apptomate_custom_text_field: ^0.0.6

Basic Usage

// Email field
CustomTextFormField(
  hintText: "Email Address",
  controller: emailController,
  focusNode: emailFocusNode,
  textInputType: TextInputType.emailAddress,
  autofillHints: [AutofillHints.email],
)

// Password field with toggle
CustomTextFormField(
  hintText: "Password",
  controller: passwordController,
  obscureText: true,
  suffixIcon: IconButton(
    icon: Icon(showPassword ? Icons.visibility : Icons.visibility_off),
    onPressed: togglePasswordVisibility,
  ),
)

Complete Example

Column(
  children: [
    // Standard text field
    CustomTextFormField(
      hintText: "Full Name",
      controller: nameController,
      textCapitalization: TextCapitalization.words,
      margin: EdgeInsets.symmetric(horizontal: 24, vertical: 8),
    ),

    // Email field with validation
    CustomTextFormField(
      hintText: "Email",
      controller: emailController,
      textInputType: TextInputType.emailAddress,
      validator: (value) {
        if (value == null || value.isEmpty) return 'Required';
        if (!value.contains('@')) return 'Invalid email';
        return null;
      },
      errorBorder: OutlineInputBorder(
        borderSide: BorderSide(color: Colors.red),
      ),
    ),

    // Phone number with masking
    CustomTextFormField(
      hintText: "Phone Number",
      controller: phoneController,
      textInputType: TextInputType.phone,
      inputFormatters: [
        FilteringTextInputFormatter.digitsOnly,
        LengthLimitingTextInputFormatter(10),
      ],
      maxLength: 10,
      isShowCounter: true,
    ),

    // Disabled field
    CustomTextFormField(
      hintText: "Read-only Field",
      controller: disabledController,
      enabled: false,
      filledColor: Colors.grey[200],
    ),
  ],
)

Parameter Reference

Core Properties

Parameter Type Required Description
controller TextEditingController Yes Controls field text
focusNode FocusNode Yes Manages focus state
hintText String Yes Placeholder text

Input Configuration

Parameter Type Default Description
textInputType TextInputType? TextInputType.text Keyboard type
obscureText bool false Hide text (for passwords)
textCapitalization TextCapitalization TextCapitalization.sentences Text case handling
inputFormatters List<TextInputFormatter>? null Input formatting rules
maxLength int? null Maximum character count
actionKeyboard TextInputAction? TextInputAction.next Keyboard action button

Visual Customization

Parameter Type Default Description
prefixIcon Widget? null Leading icon
suffixIcon Widget? null Trailing icon
filledColor Color Required Background color
isFilled bool Required Whether to fill background
enabledBorder InputBorder? Required Border when enabled
disabledBorder InputBorder? Required Border when disabled
errorBorder InputBorder? Required Border when error
hintStyle TextStyle? Required Hint text style
textStyle TextStyle? Required Input text style

Layout & Behavior

Parameter Type Default Description
margin EdgeInsets? EdgeInsets.all(16) Outer spacing
padding EdgeInsets? EdgeInsets.symmetric(vertical: 12, horizontal: 12) Inner spacing
maxLines int? 1 Lines for multiline input
isCollapsed bool? false Compact layout
isShowCounter bool false Show character counter

Functional Properties

Parameter Type Default Description
validator Function(String) Required Validation function
onChanged Function(String) Required Change callback
onSubmitField Function(String)? null Submit callback
onTap Function()? null Tap callback
enabled bool true Enable/disable field
autofillHints Iterable<String>? null Autofill suggestions

Validation Example

CustomTextFormField(
  controller: emailController,
  hintText: "Email",
  validator: (value) {
    if (value == null || value.isEmpty) {
      return 'Email is required';
    }
    if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value)) {
      return 'Enter a valid email';
    }
    return null;
  },
  errorBorder: OutlineInputBorder(
    borderSide: BorderSide(color: Colors.red),
  ),
)

Theming Guide

Create consistent field styles:

// Define border styles
final OutlineInputBorder enabledBorder = OutlineInputBorder(
  borderSide: BorderSide(color: Colors.grey),
  borderRadius: BorderRadius.circular(8),
);

final OutlineInputBorder errorBorder = OutlineInputBorder(
  borderSide: BorderSide(color: Colors.red),
  borderRadius: BorderRadius.circular(8),
);

// Reusable field configuration
CustomTextFormField(
  hintText: "Search",
  enabledBorder: enabledBorder,
  errorBorder: errorBorder,
  filledColor: Colors.white,
  isFilled: true,
  prefixIcon: Icon(Icons.search),
)

Best Practices

  1. Accessibility:

    • Provide clear labels
    • Ensure sufficient color contrast
    • Support screen readers with proper semantics
  2. Performance:

    • Reuse controllers and focus nodes
    • Avoid unnecessary rebuilds
    • Use efficient validators
  3. Security:

    • Always obscure sensitive fields
    • Sanitize input where needed
    • Consider input masking for sensitive data
  4. Internationalization:

    • Support RTL layouts
    • Localize hint texts and error messages
    • Consider locale-specific input requirements