smart_advanced_text_field 2.1.0 copy "smart_advanced_text_field: ^2.1.0" to clipboard
smart_advanced_text_field: ^2.1.0 copied to clipboard

A professional, reusable Flutter TextField package with built-in validation, formatters, theming, OTP field, and 7 styles. Designed as a small UI framework for any Flutter project.

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return SmartTextFieldThemeProvider(
      theme: SmartTextFieldTheme.light(),
      child: MaterialApp(
        title: 'SmartTextField Examples',
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
          useMaterial3: true,
        ),
        home: const ExampleHomeScreen(),
      ),
    );
  }
}

// ── Home Screen ──────────────────────────────────────────────
class ExampleHomeScreen extends StatelessWidget {
  const ExampleHomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey.shade50,
      appBar: AppBar(
        backgroundColor: Colors.indigo,
        foregroundColor: Colors.white,
        title: const Text(
          'SmartTextField',
          style: TextStyle(fontWeight: FontWeight.bold),
        ),
        centerTitle: true,
      ),
      body: ListView(
        padding: const EdgeInsets.all(20),
        children: [
          _ExampleCard(
            title: '1. Field Styles',
            subtitle: 'All 7 visual styles',
            icon: Icons.style,
            color: Colors.indigo,
            onTap: () => Navigator.push(
              context,
              MaterialPageRoute(
                builder: (_) => const FieldStylesScreen(),
              ),
            ),
          ),
          _ExampleCard(
            title: '2. Input Types',
            subtitle: 'All 13 input types',
            icon: Icons.keyboard,
            color: Colors.blue,
            onTap: () => Navigator.push(
              context,
              MaterialPageRoute(
                builder: (_) => const InputTypesScreen(),
              ),
            ),
          ),
          _ExampleCard(
            title: '3. Form Validation',
            subtitle: 'Built-in validators',
            icon: Icons.verified_user_outlined,
            color: Colors.green,
            onTap: () => Navigator.push(
              context,
              MaterialPageRoute(
                builder: (_) => const FormValidationScreen(),
              ),
            ),
          ),
          _ExampleCard(
            title: '4. OTP & PIN Field',
            subtitle: 'Auto-focus jumping boxes',
            icon: Icons.pin_outlined,
            color: Colors.orange,
            onTap: () => Navigator.push(
              context,
              MaterialPageRoute(
                builder: (_) => const OtpScreen(),
              ),
            ),
          ),
          _ExampleCard(
            title: '5. Named Constructors',
            subtitle: '.email() .password() .search() .phone()',
            icon: Icons.construction_outlined,
            color: Colors.purple,
            onTap: () => Navigator.push(
              context,
              MaterialPageRoute(
                builder: (_) => const NamedConstructorsScreen(),
              ),
            ),
          ),
          _ExampleCard(
            title: '6. Theme Support',
            subtitle: 'Light, dark and custom themes',
            icon: Icons.palette_outlined,
            color: Colors.teal,
            onTap: () => Navigator.push(
              context,
              MaterialPageRoute(
                builder: (_) => const ThemeScreen(),
              ),
            ),
          ),
          _ExampleCard(
            title: '7. Login Screen',
            subtitle: 'Real world example',
            icon: Icons.login_outlined,
            color: Colors.red,
            onTap: () => Navigator.push(
              context,
              MaterialPageRoute(
                builder: (_) => const LoginScreen(),
              ),
            ),
          ),
          _ExampleCard(
            title: '8. Register Screen',
            subtitle: 'Real world example',
            icon: Icons.person_add_outlined,
            color: Colors.pink,
            onTap: () => Navigator.push(
              context,
              MaterialPageRoute(
                builder: (_) => const RegisterScreen(),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

// ── Example Card ─────────────────────────────────────────────
class _ExampleCard extends StatelessWidget {
  final String title;
  final String subtitle;
  final IconData icon;
  final Color color;
  final VoidCallback onTap;

  const _ExampleCard({
    required this.title,
    required this.subtitle,
    required this.icon,
    required this.color,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 12),
      child: Material(
        color: Colors.white,
        borderRadius: BorderRadius.circular(16),
        elevation: 2,
        shadowColor: Colors.black12,
        child: InkWell(
          onTap: onTap,
          borderRadius: BorderRadius.circular(16),
          child: Padding(
            padding: const EdgeInsets.all(16),
            child: Row(
              children: [
                Container(
                  width: 48,
                  height: 48,
                  decoration: BoxDecoration(
                    color: color.withValues(alpha: 0.1),
                    borderRadius: BorderRadius.circular(12),
                  ),
                  child: Icon(icon, color: color, size: 24),
                ),
                const SizedBox(width: 16),
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        title,
                        style: const TextStyle(
                          fontSize: 16,
                          fontWeight: FontWeight.bold,
                          color: Colors.black87,
                        ),
                      ),
                      const SizedBox(height: 2),
                      Text(
                        subtitle,
                        style: TextStyle(
                          fontSize: 13,
                          color: Colors.grey.shade600,
                        ),
                      ),
                    ],
                  ),
                ),
                Icon(
                  Icons.arrow_forward_ios,
                  size: 16,
                  color: Colors.grey.shade400,
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

// ── Shared Widgets ───────────────────────────────────────────
class _ScreenBase extends StatelessWidget {
  final String title;
  final List<Widget> children;

  const _ScreenBase({
    required this.title,
    required this.children,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey.shade50,
      appBar: AppBar(
        backgroundColor: Colors.indigo,
        foregroundColor: Colors.white,
        title: Text(title),
        centerTitle: true,
      ),
      body: ListView(
        padding: const EdgeInsets.all(20),
        children: children,
      ),
    );
  }
}

class _Section extends StatelessWidget {
  final String label;
  final Widget child;

  const _Section({required this.label, required this.child});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 20),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            label,
            style: TextStyle(
              fontSize: 12,
              fontWeight: FontWeight.w600,
              color: Colors.grey.shade500,
              letterSpacing: 0.5,
            ),
          ),
          const SizedBox(height: 8),
          child,
        ],
      ),
    );
  }
}

// ── Screen 1: Field Styles ───────────────────────────────────
class FieldStylesScreen extends StatelessWidget {
  const FieldStylesScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return const _ScreenBase(
      title: 'Field Styles',
      children: [
        _Section(
          label: 'OUTLINED',
          child: SmartTextField(
            style: FieldStyle.outlined,
            hintText: 'Outlined style',
            labelText: 'Outlined',
            prefixIcon: Icons.border_outer,
          ),
        ),
        _Section(
          label: 'FILLED',
          child: SmartTextField(
            style: FieldStyle.filled,
            hintText: 'Filled style',
            labelText: 'Filled',
            prefixIcon: Icons.format_color_fill,
          ),
        ),
        _Section(
          label: 'UNDERLINED',
          child: SmartTextField(
            style: FieldStyle.underlined,
            hintText: 'Underlined style',
            labelText: 'Underlined',
            prefixIcon: Icons.format_underline,
          ),
        ),
        _Section(
          label: 'ROUNDED',
          child: SmartTextField(
            style: FieldStyle.rounded,
            hintText: 'Rounded style',
            labelText: 'Rounded',
            prefixIcon: Icons.radio_button_unchecked,
          ),
        ),
        _Section(
          label: 'SEARCH',
          child: SmartTextField(
            style: FieldStyle.search,
            hintText: 'Search style...',
            prefixIcon: Icons.search,
          ),
        ),
        _Section(
          label: 'MODERN',
          child: SmartTextField(
            style: FieldStyle.modern,
            hintText: 'Modern style',
            labelText: 'Modern',
            prefixIcon: Icons.auto_awesome,
          ),
        ),
        _Section(
          label: 'FLAT',
          child: SmartTextField(
            style: FieldStyle.flat,
            hintText: 'Flat style (no border)',
            prefixIcon: Icons.crop_din,
          ),
        ),
      ],
    );
  }
}

// ── Screen 2: Input Types ────────────────────────────────────
class InputTypesScreen extends StatelessWidget {
  const InputTypesScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return const _ScreenBase(
      title: 'Input Types',
      children: [
        _Section(
          label: 'EMAIL',
          child: SmartTextField(
            inputType: AppInputType.email,
            hintText: 'Enter your email',
            prefixIcon: Icons.email_outlined,
          ),
        ),
        _Section(
          label: 'PASSWORD',
          child: SmartTextField(
            inputType: AppInputType.password,
            hintText: 'Enter password',
          ),
        ),
        _Section(
          label: 'PHONE',
          child: SmartTextField(
            inputType: AppInputType.phone,
            hintText: '+92 300 1234567',
            prefixIcon: Icons.phone_outlined,
          ),
        ),
        _Section(
          label: 'NUMBER',
          child: SmartTextField(
            inputType: AppInputType.number,
            hintText: 'Enter a number',
            prefixIcon: Icons.numbers,
          ),
        ),
        _Section(
          label: 'DECIMAL',
          child: SmartTextField(
            inputType: AppInputType.decimal,
            hintText: '0.00',
            prefixIcon: Icons.calculate_outlined,
          ),
        ),
        _Section(
          label: 'CURRENCY',
          child: SmartTextField(
            inputType: AppInputType.currency,
            hintText: '0.00',
            prefixText: 'PKR  ',
            prefixIcon: Icons.attach_money,
          ),
        ),
        _Section(
          label: 'URL',
          child: SmartTextField(
            inputType: AppInputType.url,
            hintText: 'https://example.com',
            prefixIcon: Icons.link,
          ),
        ),
        _Section(
          label: 'MULTILINE',
          child: SmartTextField(
            inputType: AppInputType.multiline,
            hintText: 'Enter multiple lines of text...',
            minLines: 3,
            maxLines: 5,
          ),
        ),
        _Section(
          label: 'NAME',
          child: SmartTextField(
            inputType: AppInputType.name,
            hintText: 'Enter your full name',
            prefixIcon: Icons.person_outline,
          ),
        ),
        _Section(
          label: 'USERNAME',
          child: SmartTextField(
            inputType: AppInputType.username,
            hintText: 'Enter username',
            prefixIcon: Icons.alternate_email,
            helperText: 'Letters, numbers and underscores only',
          ),
        ),
        _Section(
          label: 'READ ONLY',
          child: SmartTextField(
            readOnly: true,
            initialValue: 'This field is read only',
            prefixIcon: Icons.lock_outline,
          ),
        ),
        _Section(
          label: 'DISABLED',
          child: SmartTextField(
            enabled: false,
            hintText: 'This field is disabled',
            prefixIcon: Icons.block,
          ),
        ),
        _Section(
          label: 'WITH CHARACTER COUNTER',
          child: SmartTextField(
            hintText: 'Max 100 characters',
            maxLength: 100,
            showCounter: true,
            prefixIcon: Icons.text_fields,
          ),
        ),
      ],
    );
  }
}

// ── Screen 3: Form Validation ────────────────────────────────
class FormValidationScreen extends StatefulWidget {
  const FormValidationScreen({super.key});

  @override
  State<FormValidationScreen> createState() => _FormValidationScreenState();
}

class _FormValidationScreenState extends State<FormValidationScreen> {
  final _formKey = GlobalKey<FormState>();
  final _passwordController = TextEditingController();
  String _status = '';

  @override
  void dispose() {
    _passwordController.dispose();
    super.dispose();
  }

  void _validate() {
    setState(() {
      _status = _formKey.currentState!.validate()
          ? '✅ All fields are valid!'
          : '❌ Please fix the errors above';
    });
  }

  void _reset() {
    _formKey.currentState!.reset();
    _passwordController.clear();
    setState(() => _status = '');
  }

  @override
  Widget build(BuildContext context) {
    return _ScreenBase(
      title: 'Form Validation',
      children: [
        Form(
          key: _formKey,
          child: Column(
            children: [
              _Section(
                label: 'EMAIL',
                child: SmartTextFormField.email(
                  validator: SmartValidators.email,
                ),
              ),
              _Section(
                label: 'PASSWORD',
                child: SmartTextFormField.password(
                  controller: _passwordController,
                  validator: SmartValidators.password,
                ),
              ),
              _Section(
                label: 'CONFIRM PASSWORD',
                child: SmartTextFormField(
                  inputType: AppInputType.password,
                  labelText: 'Confirm Password',
                  hintText: 'Re-enter your password',
                  validator: SmartValidators.confirmPassword(
                    _passwordController.text,
                  ),
                ),
              ),
              _Section(
                label: 'PHONE',
                child: SmartTextFormField.phone(
                  validator: SmartValidators.phone,
                ),
              ),
              _Section(
                label: 'USERNAME',
                child: SmartTextFormField(
                  inputType: AppInputType.username,
                  labelText: 'Username',
                  hintText: 'Enter username',
                  prefixIcon: Icons.alternate_email,
                  validator: SmartValidators.username,
                ),
              ),
              _Section(
                label: 'NAME',
                child: SmartTextFormField(
                  inputType: AppInputType.name,
                  labelText: 'Full Name',
                  hintText: 'Enter your full name',
                  prefixIcon: Icons.person_outline,
                  validator: SmartValidators.name,
                ),
              ),
              _Section(
                label: 'URL',
                child: SmartTextFormField(
                  inputType: AppInputType.url,
                  labelText: 'Website',
                  hintText: 'https://example.com',
                  prefixIcon: Icons.link,
                  validator: SmartValidators.url,
                ),
              ),
              Row(
                children: [
                  Expanded(
                    child: ElevatedButton(
                      onPressed: _validate,
                      style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.indigo,
                        foregroundColor: Colors.white,
                        padding:
                        const EdgeInsets.symmetric(vertical: 14),
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(12),
                        ),
                      ),
                      child: const Text('Validate'),
                    ),
                  ),
                  const SizedBox(width: 12),
                  Expanded(
                    child: OutlinedButton(
                      onPressed: _reset,
                      style: OutlinedButton.styleFrom(
                        padding:
                        const EdgeInsets.symmetric(vertical: 14),
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(12),
                        ),
                      ),
                      child: const Text('Reset'),
                    ),
                  ),
                ],
              ),
              if (_status.isNotEmpty) ...[
                const SizedBox(height: 16),
                Container(
                  width: double.infinity,
                  padding: const EdgeInsets.all(16),
                  decoration: BoxDecoration(
                    color: _status.contains('✅')
                        ? Colors.green.shade50
                        : Colors.red.shade50,
                    borderRadius: BorderRadius.circular(12),
                    border: Border.all(
                      color: _status.contains('✅')
                          ? Colors.green
                          : Colors.red,
                    ),
                  ),
                  child: Text(
                    _status,
                    style: TextStyle(
                      fontSize: 15,
                      fontWeight: FontWeight.bold,
                      color: _status.contains('✅')
                          ? Colors.green.shade700
                          : Colors.red.shade700,
                    ),
                    textAlign: TextAlign.center,
                  ),
                ),
              ],
            ],
          ),
        ),
      ],
    );
  }
}

// ── Screen 4: OTP ────────────────────────────────────────────
class OtpScreen extends StatefulWidget {
  const OtpScreen({super.key});

  @override
  State<OtpScreen> createState() => _OtpScreenState();
}

class _OtpScreenState extends State<OtpScreen> {
  String _otp6 = '';
  String _pin4 = '';

  @override
  Widget build(BuildContext context) {
    return _ScreenBase(
      title: 'OTP & PIN Field',
      children: [
        _Section(
          label: '6-DIGIT OTP',
          child: Column(
            children: [
              SmartOtpField(
                length: 6,
                onCompleted: (otp) => setState(() => _otp6 = otp),
                onChanged: (otp) => setState(() => _otp6 = otp),
              ),
              if (_otp6.isNotEmpty) ...[
                const SizedBox(height: 12),
                Text(
                  'OTP: $_otp6',
                  style: const TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.bold,
                    color: Colors.indigo,
                  ),
                ),
              ],
            ],
          ),
        ),
        _Section(
          label: '4-DIGIT PIN (OBSCURED)',
          child: Column(
            children: [
              SmartOtpField(
                length: 4,
                obscureText: true,
                boxWidth: 64,
                boxHeight: 72,
                borderRadius: 16,
                onCompleted: (pin) => setState(() => _pin4 = pin),
                onChanged: (pin) => setState(() => _pin4 = pin),
              ),
              if (_pin4.length == 4) ...[
                const SizedBox(height: 12),
                const Text(
                  '✅ PIN entered',
                  style: TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.bold,
                    color: Colors.green,
                  ),
                ),
              ],
            ],
          ),
        ),
      ],
    );
  }
}

// ── Screen 5: Named Constructors ─────────────────────────────
class NamedConstructorsScreen extends StatelessWidget {
  const NamedConstructorsScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return _ScreenBase(
      title: 'Named Constructors',
      children: [
        _Section(
          label: 'SmartTextField.email()',
          child: SmartTextField.email(
            onChanged: (_) {},
          ),
        ),
        _Section(
          label: 'SmartTextField.password()',
          child: SmartTextField.password(
            onChanged: (_) {},
          ),
        ),
        _Section(
          label: 'SmartTextField.search()',
          child: SmartTextField.search(
            onChanged: (_) {},
          ),
        ),
        _Section(
          label: 'SmartTextField.phone()',
          child: SmartTextField.phone(
            onChanged: (_) {},
          ),
        ),
        _Section(
          label: 'SmartTextFormField.email()',
          child: SmartTextFormField.email(
            validator: SmartValidators.email,
          ),
        ),
        _Section(
          label: 'SmartTextFormField.password()',
          child: SmartTextFormField.password(
            validator: SmartValidators.password,
          ),
        ),
        _Section(
          label: 'SmartTextFormField.phone()',
          child: SmartTextFormField.phone(
            validator: SmartValidators.phone,
          ),
        ),
      ],
    );
  }
}

// ── Screen 6: Theme Support ──────────────────────────────────
class ThemeScreen extends StatefulWidget {
  const ThemeScreen({super.key});

  @override
  State<ThemeScreen> createState() => _ThemeScreenState();
}

class _ThemeScreenState extends State<ThemeScreen> {
  bool _isDark = false;

  @override
  Widget build(BuildContext context) {
    final theme = _isDark
        ? SmartTextFieldTheme.dark()
        : SmartTextFieldTheme.light();

    return SmartTextFieldThemeProvider(
      theme: theme,
      child: Scaffold(
        backgroundColor: _isDark ? Colors.grey.shade900 : Colors.grey.shade50,
        appBar: AppBar(
          backgroundColor: Colors.indigo,
          foregroundColor: Colors.white,
          title: const Text('Theme Support'),
          centerTitle: true,
          actions: [
            Switch(
              value: _isDark,
              onChanged: (v) => setState(() => _isDark = v),
              activeThumbColor: Colors.white,
            ),
          ],
        ),
        body: ListView(
          padding: const EdgeInsets.all(20),
          children: [
            _Section(
              label: 'OUTLINED',
              child: SmartTextField(
                style: FieldStyle.outlined,
                hintText: 'Outlined field',
                labelText: 'Email',
                prefixIcon: Icons.email_outlined,
                themeOverride: theme,
              ),
            ),
            _Section(
              label: 'FILLED',
              child: SmartTextField(
                style: FieldStyle.filled,
                hintText: 'Filled field',
                labelText: 'Password',
                inputType: AppInputType.password,
                themeOverride: theme,
              ),
            ),
            _Section(
              label: 'ROUNDED',
              child: SmartTextField(
                style: FieldStyle.rounded,
                hintText: 'Rounded field',
                labelText: 'Phone',
                prefixIcon: Icons.phone_outlined,
                themeOverride: theme,
              ),
            ),
            _Section(
              label: 'CUSTOM PURPLE THEME',
              child: SmartTextField(
                style: FieldStyle.outlined,
                hintText: 'Custom theme field',
                labelText: 'Custom',
                prefixIcon: Icons.palette_outlined,
                themeOverride: SmartTextFieldTheme(
                  borderRadius: 20,
                  borderColor: Colors.purple.shade200,
                  focusedBorderColor: Colors.purple,
                  filledColor: Colors.purple.shade50,
                  textColor: Colors.purple.shade900,
                  hintColor: Colors.purple.shade300,
                  labelColor: Colors.purple,
                  iconColor: Colors.purple,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// ── Screen 7: Login Screen ───────────────────────────────────
class LoginScreen extends StatefulWidget {
  const LoginScreen({super.key});

  @override
  State<LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  final _formKey = GlobalKey<FormState>();
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();
  bool _isLoading = false;

  @override
  void dispose() {
    _emailController.dispose();
    _passwordController.dispose();
    super.dispose();
  }

  void _login() async {
    if (_formKey.currentState!.validate()) {
      setState(() => _isLoading = true);
      await Future.delayed(const Duration(seconds: 2));
      setState(() => _isLoading = false);
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('✅ Login Successful!'),
            backgroundColor: Colors.green,
          ),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: SafeArea(
        child: SingleChildScrollView(
          padding: const EdgeInsets.all(24),
          child: Form(
            key: _formKey,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const SizedBox(height: 48),
                const Text(
                  'Welcome Back 👋',
                  style: TextStyle(
                    fontSize: 32,
                    fontWeight: FontWeight.bold,
                    color: Colors.black87,
                  ),
                ),
                const SizedBox(height: 8),
                Text(
                  'Sign in to your account',
                  style: TextStyle(
                    fontSize: 16,
                    color: Colors.grey.shade600,
                  ),
                ),
                const SizedBox(height: 48),
                SmartTextFormField.email(
                  controller: _emailController,
                  validator: SmartValidators.email,
                  style: FieldStyle.outlined,
                ),
                const SizedBox(height: 16),
                SmartTextFormField.password(
                  controller: _passwordController,
                  validator: SmartValidators.required(),
                  style: FieldStyle.outlined,
                ),
                const SizedBox(height: 12),
                Align(
                  alignment: Alignment.centerRight,
                  child: TextButton(
                    onPressed: () {},
                    child: const Text('Forgot Password?'),
                  ),
                ),
                const SizedBox(height: 24),
                SizedBox(
                  width: double.infinity,
                  height: 52,
                  child: ElevatedButton(
                    onPressed: _isLoading ? null : _login,
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.indigo,
                      foregroundColor: Colors.white,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(14),
                      ),
                    ),
                    child: _isLoading
                        ? const SizedBox(
                      width: 24,
                      height: 24,
                      child: CircularProgressIndicator(
                        color: Colors.white,
                        strokeWidth: 2,
                      ),
                    )
                        : const Text(
                      'Sign In',
                      style: TextStyle(
                        fontSize: 16,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                ),
                const SizedBox(height: 24),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text(
                      "Don't have an account? ",
                      style: TextStyle(color: Colors.grey.shade600),
                    ),
                    TextButton(
                      onPressed: () => Navigator.pushReplacement(
                        context,
                        MaterialPageRoute(
                          builder: (_) => const RegisterScreen(),
                        ),
                      ),
                      child: const Text('Sign Up'),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

// ── Screen 8: Register Screen ────────────────────────────────
class RegisterScreen extends StatefulWidget {
  const RegisterScreen({super.key});

  @override
  State<RegisterScreen> createState() => _RegisterScreenState();
}

class _RegisterScreenState extends State<RegisterScreen> {
  final _formKey = GlobalKey<FormState>();
  final _passwordController = TextEditingController();
  bool _isLoading = false;

  @override
  void dispose() {
    _passwordController.dispose();
    super.dispose();
  }

  void _register() async {
    if (_formKey.currentState!.validate()) {
      setState(() => _isLoading = true);
      await Future.delayed(const Duration(seconds: 2));
      setState(() => _isLoading = false);
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('✅ Account Created Successfully!'),
            backgroundColor: Colors.green,
          ),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: SafeArea(
        child: SingleChildScrollView(
          padding: const EdgeInsets.all(24),
          child: Form(
            key: _formKey,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const SizedBox(height: 48),
                const Text(
                  'Create Account ✨',
                  style: TextStyle(
                    fontSize: 32,
                    fontWeight: FontWeight.bold,
                    color: Colors.black87,
                  ),
                ),
                const SizedBox(height: 8),
                Text(
                  'Fill in your details to get started',
                  style: TextStyle(
                    fontSize: 16,
                    color: Colors.grey.shade600,
                  ),
                ),
                const SizedBox(height: 36),
                SmartTextFormField(
                  inputType: AppInputType.name,
                  labelText: 'Full Name',
                  hintText: 'Enter your full name',
                  prefixIcon: Icons.person_outline,
                  validator: SmartValidators.name,
                ),
                const SizedBox(height: 16),
                SmartTextFormField(
                  inputType: AppInputType.username,
                  labelText: 'Username',
                  hintText: 'Choose a username',
                  prefixIcon: Icons.alternate_email,
                  validator: SmartValidators.username,
                  helperText: 'Letters, numbers and underscores only',
                ),
                const SizedBox(height: 16),
                SmartTextFormField.email(
                  validator: SmartValidators.email,
                ),
                const SizedBox(height: 16),
                SmartTextFormField.phone(
                  validator: SmartValidators.phone,
                ),
                const SizedBox(height: 16),
                SmartTextFormField.password(
                  controller: _passwordController,
                  validator: SmartValidators.password,
                ),
                const SizedBox(height: 16),
                SmartTextFormField(
                  inputType: AppInputType.password,
                  labelText: 'Confirm Password',
                  hintText: 'Re-enter your password',
                  validator: SmartValidators.confirmPassword(
                    _passwordController.text,
                  ),
                ),
                const SizedBox(height: 32),
                SizedBox(
                  width: double.infinity,
                  height: 52,
                  child: ElevatedButton(
                    onPressed: _isLoading ? null : _register,
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.indigo,
                      foregroundColor: Colors.white,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(14),
                      ),
                    ),
                    child: _isLoading
                        ? const SizedBox(
                      width: 24,
                      height: 24,
                      child: CircularProgressIndicator(
                        color: Colors.white,
                        strokeWidth: 2,
                      ),
                    )
                        : const Text(
                      'Create Account',
                      style: TextStyle(
                        fontSize: 16,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                ),
                const SizedBox(height: 24),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text(
                      'Already have an account? ',
                      style: TextStyle(color: Colors.grey.shade600),
                    ),
                    TextButton(
                      onPressed: () => Navigator.pushReplacement(
                        context,
                        MaterialPageRoute(
                          builder: (_) => const LoginScreen(),
                        ),
                      ),
                      child: const Text('Sign In'),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
2
likes
0
points
583
downloads

Publisher

unverified uploader

Weekly Downloads

A professional, reusable Flutter TextField package with built-in validation, formatters, theming, OTP field, and 7 styles. Designed as a small UI framework for any Flutter project.

Repository (GitHub)
View/report issues

Topics

#textfield #form #input #validation #otp

License

unknown (license)

Dependencies

flutter, intl

More

Packages that depend on smart_advanced_text_field