floating_label_inputs 0.1.0 copy "floating_label_inputs: ^0.1.0" to clipboard
floating_label_inputs: ^0.1.0 copied to clipboard

A Flutter package providing highly customizable text input fields with animated floating labels, error states, and height clamping.

example/lib/main.dart

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

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Floating Label Input Demo',
      theme: ThemeData(
        brightness: Brightness.dark,
        scaffoldBackgroundColor: const Color(0xFF1D2B3A),
        colorScheme: ColorScheme.fromSwatch(brightness: Brightness.dark)
            .copyWith(error: Colors.orangeAccent),
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _formKey = GlobalKey<FormState>();

  final TextEditingController _nameController = TextEditingController();
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _companyEmailController = TextEditingController(); // New controller

  // FocusNodes are optional but good for managing focus programmatically
  final FocusNode _nameFocusNode = FocusNode();
  final FocusNode _emailFocusNode = FocusNode();
  final FocusNode _companyEmailFocusNode = FocusNode(); // New FocusNode

  @override
  void dispose() {
    _nameController.dispose();
    _emailController.dispose();
    _companyEmailController.dispose(); // Dispose new controller
    _nameFocusNode.dispose();
    _emailFocusNode.dispose();
    _companyEmailFocusNode.dispose(); // Dispose new FocusNode
    super.dispose();
  }

  void _submitForm() {
    if (_formKey.currentState!.validate()) {
      ScaffoldMessenger.of(context)
          .showSnackBar(const SnackBar(content: Text('Processing Data')));
      print('Form is valid!');
      print('Name: ${_nameController.text}');
      print('Email: ${_emailController.text}');
      print('Company Email: ${_companyEmailController.text}'); // Print new field
    } else {
      print('Form is invalid!');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Floating Label Demo App'),
        backgroundColor: const Color(0xFF1D2B3A),
        elevation: 0,
      ),
      body: Center(
        child: SingleChildScrollView(
          padding: const EdgeInsets.all(30.0),
          child: Form(
            key: _formKey,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                FloatingAnimatedInput(
                  labelText: 'Full Name',
                  controller: _nameController,
                  focusNode: _nameFocusNode,
                  textStyle: const TextStyle(color: Colors.white, fontSize: 16),
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Please enter your name';
                    }
                    if (value.length < 3) {
                      return 'Name must be at least 3 characters';
                    }
                    return null;
                  },
                  autovalidateMode: AutovalidateMode.onUserInteraction,
                  errorTextStyle: TextStyle(color: Colors.yellow[700], fontSize: 13, fontWeight: FontWeight.bold),
                  errorBorderSide: BorderSide(color: Colors.yellow[700]!, width: 1.5),
                  focusedErrorBorderSide: BorderSide(color: Colors.yellow[900]!, width: 2.0),
                ),
                const SizedBox(height: 20),
                FloatingAnimatedInput(
                  labelText: 'Personal Email',
                  controller: _emailController,
                  focusNode: _emailFocusNode,
                  textStyle: const TextStyle(color: Colors.white, fontSize: 16),
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Please enter your email';
                    }
                    final emailRegex = RegExp(r'^[^@]+@[^@]+\.[^@]+');
                    if (!emailRegex.hasMatch(value)) {
                      return 'Enter a valid email address';
                    }
                    return null;
                  },
                  autovalidateMode: AutovalidateMode.onUserInteraction,
                ),
                const SizedBox(height: 20), // Added spacing
                FloatingAnimatedInput( // New field for Company Email
                  labelText: 'Company Email',
                  controller: _companyEmailController,
                  focusNode: _companyEmailFocusNode,
                  textStyle: const TextStyle(color: Colors.white, fontSize: 16),
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Please enter your company email';
                    }
                    final emailRegex = RegExp(r'^[^@]+@[^@]+\.[^@]+');
                    if (!emailRegex.hasMatch(value)) {
                      return 'Enter a valid email address format';
                    }
                    const String requiredDomain = '@test.com';
                    if (!value.toLowerCase().endsWith(requiredDomain)) {
                      return 'Email must be from the $requiredDomain domain';
                    }
                    return null; // Valid
                  },
                  autovalidateMode: AutovalidateMode.onUserInteraction,
                  // You can customize error styles for this field too if needed
                  // errorTextStyle: TextStyle(color: Colors.cyanAccent, fontSize: 13),
                  // errorBorderSide: BorderSide(color: Colors.cyanAccent, width: 1.5),
                ),
                const SizedBox(height: 30),
                ElevatedButton(
                  style: ElevatedButton.styleFrom(
                    backgroundColor: const Color(0xFF00DFC4),
                    padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 15),
                    textStyle: const TextStyle(fontSize: 16, color: Color(0xFF1D2B3A)),
                  ),
                  onPressed: _submitForm,
                  child: const Text('Submit', style: TextStyle(color: Color(0xFF1D2B3A))),
                ),
                const SizedBox(height: 40),
                FloatingAnimatedInput(
                    labelText: 'Square TextField',
                  textFieldBorderRadius: BorderRadius.circular(0),
                ),
                const SizedBox(height: 30),
                FloatingAnimatedInput(
                    labelText: 'Rounded TextField',
                    textFieldBorderRadius: BorderRadius.circular(25.0),
                  height: 45,
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}
1
likes
160
points
32
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter package providing highly customizable text input fields with animated floating labels, error states, and height clamping.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on floating_label_inputs