flexi_form_field 2.0.1 copy "flexi_form_field: ^2.0.1" to clipboard
flexi_form_field: ^2.0.1 copied to clipboard

PlatformiOSweb

A flexible and customizable TextFormField widget for Flutter with built-in validation, formatting, mandatory fields, prefix/suffix icons, and more.

example/lib/main.dart

import 'package:flexi_form_field/flexi_form_field.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flexi Form Field Showcase',
      theme: ThemeData(
        useMaterial3: true,
        primaryColor: const Color(0xFF673AB7),
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF673AB7),
          primary: const Color(0xFF673AB7),
        ),
        scaffoldBackgroundColor: const Color(0xFFF8F9FA),
      ),
      home: const ExampleScreen(),
    );
  }
}

class ExampleScreen extends StatefulWidget {
  const ExampleScreen({super.key});

  @override
  State<ExampleScreen> createState() => _ExampleScreenState();
}

class _ExampleScreenState extends State<ExampleScreen> {
  int _currentStep = 0;
  int _tabIndex = 0;

  final Map<String, TextEditingController> _controllers = {
    'text': TextEditingController(),
    'date': TextEditingController(),
    'time': TextEditingController(),
    'dateTime': TextEditingController(),
    'autoComplete': TextEditingController(),
  };

  String? _selectedValue;

  final FlexiFormTheme _appTheme = const FlexiFormTheme(
    primaryColor: Color(0xFF673AB7),
    borderRadius: BorderRadius.all(Radius.circular(12)),
    fillColor: Color(0xFFF3E5F5),
  );

  final List<String> _categories = ["Text Inputs", "Date & Time", "Interactive", "Real Form"];
  final List<String> _styles = ["Outline", "Filled", "Rounded", "Underline", "Minimal"];

  FlexiFieldStyle get _selectedStyle {
    switch (_tabIndex) {
      case 1:
        return FlexiFieldStyle.filled;
      case 2:
        return FlexiFieldStyle.rounded;
      case 3:
        return FlexiFieldStyle.underline;
      case 4:
        return FlexiFieldStyle.minimal;
      default:
        return FlexiFieldStyle.outline;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          "Flexi Widgets Showcase",
          style: TextStyle(fontWeight: FontWeight.bold),
        ),
        centerTitle: true,
        elevation: 0,
        backgroundColor: Colors.transparent,
      ),
      body: SafeArea(
        child: Column(
          children: [
            const SizedBox(height: 10),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 20),
              child: _sectionHeader("Stepper"),
            ),
            FlexiStepper(
              currentStep: _currentStep,
              stepTitles: _categories,
              onStepChange: (index) => setState(() => _currentStep = index),
            ),
            const SizedBox(height: 20),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 20),
              child: _sectionHeader("Tab Bar"),
            ),
            FlexiTabBar(
              tabs: _styles,
              currentIndex: _tabIndex,
              onChanged: (index) => setState(() => _tabIndex = index),
              backgroundColor: Colors.grey.shade200,
              activeColor: const Color(0xFF673AB7),
              fontSize: 12,
              borderRadius: BorderRadius.circular(5),
            ),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: _buildContent(),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildContent() {
    return AnimatedSwitcher(
      duration: const Duration(milliseconds: 300),
      child: ListView(
        key: ValueKey("$_currentStep-$_tabIndex"),
        physics: const BouncingScrollPhysics(),
        children: [
          if (_currentStep == 0) ..._buildTextInputs(),
          if (_currentStep == 1) ..._buildPickers(),
          if (_currentStep == 2) ..._buildInteractive(),
          if (_currentStep == 3) _buildRealForm(),
        ],
      ),
    );
  }

  List<Widget> _buildTextInputs() {
    return [
      _sectionHeader("Standard Input"),
      FlexiFormField(
        controller: _controllers['text']!,
        label: "Username",
        hint: "Enter your username",
        fieldStyle: _selectedStyle,
        theme: _appTheme,
        isMandatory: true,
      ),
      const SizedBox(height: 20),
      _sectionHeader("Selection Dropdown"),
      FlexiDropDown(
        label: "Department",
        value: _selectedValue,
        fieldStyle: _selectedStyle,
        theme: _appTheme,
        items: const [
          DropdownMenuItem(value: "IT", child: Text("Information Technology")),
          DropdownMenuItem(value: "HR", child: Text("Human Resources")),
          DropdownMenuItem(value: "FIN", child: Text("Finance")),
        ],
        onChanged: (val) => setState(() => _selectedValue = val),
      ),
      const SizedBox(height: 20),
      _sectionHeader("Auto-Complete Field"),
      FlexiAutoComplete<String>(
        controller: _controllers['autoComplete']!,
        label: "Favorite Fruit",
        hint: "Start typing...",
        options: const ["Apple", "Banana", "Cherry", "Date", "Elderberry", "Fig", "Grape", "Honeydew"],
        itemLabelBuilder: (item) => item,
        onSelected: (val) => debugPrint("Selected: $val"),
        fieldStyle: _selectedStyle,
        theme: _appTheme,
      ),
    ];
  }

  List<Widget> _buildPickers() {
    return [
      _sectionHeader("Date Selection"),
      FlexiDatePicker(
        controller: _controllers['date']!,
        label: "Birth Date",
        fieldStyle: _selectedStyle,
        theme: _appTheme,
        isMandatory: true,
      ),
      const SizedBox(height: 20),
      _sectionHeader("Time Selection"),
      FlexiTimePicker(
        controller: _controllers['time']!,
        label: "Meeting Time",
        fieldStyle: _selectedStyle,
        theme: _appTheme,
      ),
      const SizedBox(height: 20),
      _sectionHeader("Combined Picker"),
      FlexiDateTimePicker(
        controller: _controllers['dateTime']!,
        label: "Appointment",
        fieldStyle: _selectedStyle,
        theme: _appTheme,
      ),
    ];
  }

  List<Widget> _buildInteractive() {
    return [
      _sectionHeader("Flexible Timer"),
      const FlexiTimer(),
      const SizedBox(height: 30),
      _sectionHeader("Custom Buttons"),
      Wrap(
        spacing: 12,
        runSpacing: 12,
        alignment: WrapAlignment.center,
        children: [
          FlexiButton(
            width: 140,
            color: const Color(0xFF673AB7),
            onTap: () {},
            child: const Text("Primary", style: TextStyle(color: Colors.white)),
          ),
          FlexiButton(
            width: 140,
            gradient: const LinearGradient(colors: [Colors.blue, Colors.cyan]),
            onTap: () {},
            child: const Text("Gradient", style: TextStyle(color: Colors.white)),
          ),
          FlexiButton(
            width: 140,
            elevation: 2,
            color: Colors.white,
            borderRadius: BorderRadius.circular(8),
            border: Border.all(color: Colors.grey.shade300),
            onTap: () {},
            child: const Text("Outlined", style: TextStyle(color: Colors.black)),
          ),
        ],
      ),
    ];
  }

  Widget _buildRealForm() {
    final formKey = GlobalKey<FormState>();
    return Column(
      children: [
        _sectionHeader("Registration Example"),
        Material(
          color: Colors.white,
          borderRadius: BorderRadius.circular(20),
          elevation: 4,
          shadowColor: Colors.black12,
          child: Padding(
            padding: const EdgeInsets.all(24.0),
            child: Form(
              key: formKey,
              child: Column(
                children: [
                  FlexiFormField(
                    label: "Full Name",
                    prefixIcon: const Icon(Icons.person_outline),
                    fieldStyle: _selectedStyle,
                    theme: _appTheme,
                    isMandatory: true,
                  ),
                  const SizedBox(height: 16),
                  FlexiFormField(
                    label: "Email Address",
                    prefixIcon: const Icon(Icons.email_outlined),
                    fieldStyle: _selectedStyle,
                    theme: _appTheme,
                    isMandatory: true,
                  ),
                  const SizedBox(height: 16),
                  FlexiDatePicker(
                    controller: TextEditingController(),
                    label: "Date of Birth",
                    prefixIcon: const Icon(Icons.calendar_today_outlined),
                    fieldStyle: _selectedStyle,
                    theme: _appTheme,
                  ),
                  const SizedBox(height: 24),
                  FlexiButton(
                    height: 50,
                    width: double.infinity,
                    gradient: const LinearGradient(colors: [Color(0xFF673AB7), Color(0xFF9575CD)]),
                    onTap: () {
                      if (formKey.currentState!.validate()) {
                        ScaffoldMessenger.of(context).showSnackBar(
                          const SnackBar(content: Text("Processing Data...")),
                        );
                      }
                    },
                    child: const Text(
                      "SIGN UP",
                      style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 16),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ],
    );
  }

  Widget _sectionHeader(String title) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 12),
      child: Row(
        children: [
          Container(
            width: 4,
            height: 20,
            decoration: BoxDecoration(
              color: const Color(0xFF673AB7),
              borderRadius: BorderRadius.circular(2),
            ),
          ),
          const SizedBox(width: 8),
          Text(
            title,
            style: const TextStyle(
              fontSize: 18,
              fontWeight: FontWeight.bold,
              color: Colors.black87,
            ),
          ),
        ],
      ),
    );
  }
}
3
likes
150
points
131
downloads

Publisher

unverified uploader

Weekly Downloads

A flexible and customizable TextFormField widget for Flutter with built-in validation, formatting, mandatory fields, prefix/suffix icons, and more.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter, flutter_typeahead, intl

More

Packages that depend on flexi_form_field