super_daily_extensions 1.1.3 copy "super_daily_extensions: ^1.1.3" to clipboard
super_daily_extensions: ^1.1.3 copied to clipboard

A Flutter toolkit featuring country & city pickers, form validators, universal auto-masking, custom UI widgets, and daily developer extensions.

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'super_daily_extensions Showcase',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF6C63FF),
          brightness: Brightness.light,
        ),
        useMaterial3: true,
      ),
      home: const ExampleHomeScreen(),
    );
  }
}

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

  @override
  State<ExampleHomeScreen> createState() => _ExampleHomeScreenState();
}

class _ExampleHomeScreenState extends State<ExampleHomeScreen>
    with SingleTickerProviderStateMixin {
  late TabController _tabController;

  // ─── Country State ───
  Country? _selectedCountry;
  String? _selectedCity;
  String _phoneNumber = '';

  // ─── Pickers State ───
  DateTime? _selectedDate = DateTime.now();
  TimeOfDay? _selectedTime = const TimeOfDay(hour: 10, minute: 30);
  DateTime? _startDate = DateTime.now();
  DateTime? _endDate = DateTime.now().add(const Duration(days: 7));

  // ─── Button Loading State ───
  bool _isButtonLoading = false;

  // ─── Form & Validation State ───
  final _formKey = GlobalKey<FormState>();
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();
  final _confirmPasswordController = TextEditingController();
  final _cnicController = TextEditingController();
  final _phoneController = TextEditingController();
  bool _useSimpleValidators = true;
  int _selectedIdLength = 13;
  String _selectedIdMask = '#####-#######-#';
  String _selectedIdHint = '35202-1234567-1 (Auto-formatted)';

  // ─── Sample Base64 image (small blue square png) ───
  static const String _sampleBase64 =
      'iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAAADZJREFUeJztwTEBAAAAwqD1T20LL6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4HUAFPAAATG+yP4AAAAASUVORK5CYII=';

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 6, vsync: this);
  }

  @override
  void dispose() {
    _tabController.dispose();
    _emailController.dispose();
    _passwordController.dispose();
    _confirmPasswordController.dispose();
    _cnicController.dispose();
    _phoneController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const CustomText(
          'Super Daily Extensions',
          variant: CustomTextVariant.heading,
        ),
        centerTitle: true,
        bottom: PreferredSize(
          preferredSize: const Size.fromHeight(50),
          child: CustomContainer(
            height: 42,
            margin: const EdgeInsets.only(left: 12, right: 12, bottom: 0),
            padding: const EdgeInsets.all(2),
            radius: 8,
            color: Colors.grey.shade100,
            border: Border.all(color: Colors.grey.shade300, width: 0.8),
            boxShadow: [
              BoxShadow(
                color: Colors.black.withValues(alpha: 0.03),
                blurRadius: 6,
                offset: const Offset(0, 2),
              ),
            ],
            child: TabBar(
              controller: _tabController,
              isScrollable: true,
              tabAlignment: TabAlignment.start,
              dividerColor: Colors.transparent,
              indicatorSize: TabBarIndicatorSize.tab,
              splashBorderRadius: BorderRadius.circular(8),
              indicator: BoxDecoration(
                borderRadius: BorderRadius.circular(8),
                color: const Color(0xFF6C63FF),
              ),
              labelColor: Colors.white,
              unselectedLabelColor: Colors.grey.shade700,
              labelStyle: const TextStyle(
                fontWeight: FontWeight.w600,
                fontSize: 13,
              ),
              unselectedLabelStyle: const TextStyle(
                fontWeight: FontWeight.w500,
                fontSize: 13,
              ),
              tabs: const [
                Tab(
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 10),
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Icon(Icons.widgets_outlined, size: 16),
                        SizedBox(width: 6),
                        Text('UI Widgets'),
                      ],
                    ),
                  ),
                ),
                Tab(
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 10),
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Icon(Icons.verified_user_outlined, size: 16),
                        SizedBox(width: 6),
                        Text('Validators & Shortcuts'),
                      ],
                    ),
                  ),
                ),
                Tab(
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 10),
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Icon(Icons.calendar_today_outlined, size: 16),
                        SizedBox(width: 6),
                        Text('Pickers & Media'),
                      ],
                    ),
                  ),
                ),
                Tab(
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 10),
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Icon(Icons.notifications_active_outlined, size: 16),
                        SizedBox(width: 6),
                        Text('Dialogs & Alerts'),
                      ],
                    ),
                  ),
                ),
                Tab(
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 10),
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Icon(Icons.public_outlined, size: 16),
                        SizedBox(width: 6),
                        Text('Countries & Cities'),
                      ],
                    ),
                  ),
                ),
                Tab(
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 10),
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Icon(Icons.table_chart_outlined, size: 16),
                        SizedBox(width: 6),
                        Text('Data Table'),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: [
          _buildUIWidgetsTab(),
          _buildValidatorsTab(),
          _buildPickersTab(),
          _buildDialogsTab(),
          _buildCountryTab(),
          _buildDataTableTab(),
        ],
      ),
    );
  }

  // ══════════════════════════════════════════════════════════════════════════
  // TAB 1: UI WIDGETS (Buttons, Container, Text, TextFields)
  // ══════════════════════════════════════════════════════════════════════════
  Widget _buildUIWidgetsTab() {
    return SingleChildScrollView(
      padding: const EdgeInsets.all(12),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // ─── 1. Custom Buttons ───
          CustomText(
            '1. CustomButton & Variants',
            fontSize: 16,
            variant: CustomTextVariant.heading,
          ),
          CustomGap(height: 8),
          CustomButton.primary(
            title: 'Primary Button',
            icon: Icons.check_circle_outline,
            onPressed: () =>
                context.showCustomSnackBar('Primary button tapped!'),
          ),
          CustomGap(height: 10),
          CustomButton.outlined(
            title: 'Outlined Button',
            icon: Icons.refresh,
            onPressed: () =>
                context.showCustomSnackBar('Outlined button tapped!'),
          ),
          CustomGap(height: 10),
          CustomButton.text(
            title: 'Text Button (Flat)',
            icon: Icons.arrow_forward,
            onPressed: () => context.showCustomSnackBar('Text button tapped!'),
          ),
          CustomGap(height: 10),
          Row(
            children: [
              Expanded(
                child: CustomButton(
                  title: 'Loading Button',
                  isLoading: _isButtonLoading,
                  onPressed: () {
                    setState(() => _isButtonLoading = true);
                    Future.delayed(const Duration(seconds: 2), () {
                      if (mounted) setState(() => _isButtonLoading = false);
                    });
                  },
                ),
              ),
              CustomGap(
                width: 12,
              ),
              Switch(
                value: _isButtonLoading,
                onChanged: (val) => setState(() => _isButtonLoading = val),
              ),
            ],
          ),

          CustomGap(height: 10),
          const Divider(),
          CustomGap(height: 10),

          // ─── 2. CustomTextField ───
          CustomText(
            '2. CustomTextField with Status Borders',
            fontSize: 16,
            variant: CustomTextVariant.heading,
          ),
          CustomGap(height: 16),
          const CustomTextField(
            labelText: 'Normal Status Field',
            hintText: 'Enter text here',
            prefixIcon: Icon(Icons.edit_outlined),
            status: TextFieldStatus.normal,
          ),
          CustomGap(height: 10),
          const CustomTextField(
            labelText: 'Success Status Field',
            hintText: 'user@example.com',
            prefixIcon: Icon(Icons.check_circle_outline, color: Colors.green),
            status: TextFieldStatus.success,
          ),
          CustomGap(height: 10),
          const CustomTextField(
            labelText: 'Warning Status Field',
            hintText: 'Weak password',
            prefixIcon: Icon(Icons.warning_amber_outlined, color: Colors.amber),
            status: TextFieldStatus.warning,
          ),
          CustomGap(height: 10),
          const CustomTextField(
            labelText: 'Error Status Field',
            hintText: 'Invalid phone number',
            prefixIcon: Icon(Icons.error_outline, color: Colors.red),
            status: TextFieldStatus.error,
          ),
          CustomGap(height: 10),
          const CustomTextField(
            labelText: 'Rounded Variant',
            hintText: 'Search anything...',
            variant: TextFieldVariant.rounded,
            prefixIcon: Icon(Icons.search),
          ),
          CustomGap(height: 10),
          const CustomTextField.password(
            labelText: 'Password Field with Eye Toggle',
            hintText: 'Tap eye icon to show/hide password',
          ),
          CustomGap(height: 10),
          const CustomTextField(
            labelText: 'Credit Card (Universal Mask)',
            hintText: '#### #### #### ####',
            mask: '#### #### #### ####',
            prefixIcon: Icon(Icons.credit_card_outlined),
          ),

          CustomGap(height: 10),
          const Divider(),
          CustomGap(height: 10),

          // ─── 3. CustomContainer ───
          CustomText(
            '3. CustomContainer & Widget Extensions',
            fontSize: 16,
            variant: CustomTextVariant.heading,
          ),
          CustomGap(height: 16),
          CustomContainer(
            w: 90,
            radius: 12,
            gradient: const LinearGradient(
              colors: [Color(0xFF6C63FF), Color(0xFF3F3D56)],
            ),
            padding: const EdgeInsets.all(16),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const CustomText(
                  'CustomContainer with Gradient',
                  color: Colors.white,
                  fontWeight: FontWeight.bold,
                  fontSize: 16,
                ),
                CustomGap(height: 8),
                const CustomText(
                  'Width is responsive (90% of safe screen width).',
                  color: Colors.white70,
                  fontSize: 13,
                ),
              ],
            ),
          ),
          CustomGap(height: 16),
          // Chained extension usage:
          CustomText('Widget wrapped via .toCustomContainer() extension')
              .toCustomContainer(
            radius: 10,
            color: Colors.deepPurple.withValues(alpha: 0.08),
            padding: const EdgeInsets.all(14),
            border: Border.all(color: Colors.deepPurple.withValues(alpha: 0.3)),
          ),
        ],
      ),
    );
  }

  // ══════════════════════════════════════════════════════════════════════════
  // TAB 2: VALIDATORS & SHORTCUTS (Forms, Regex Helpers, Keyboard & Theme)
  // ══════════════════════════════════════════════════════════════════════════
  Widget _buildValidatorsTab() {
    return SingleChildScrollView(
      padding: const EdgeInsets.all(12),
      child: Form(
        key: _formKey,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // Header / Intro Card
            CustomContainer(
              radius: 12,
              color: const Color(0xFF6C63FF).withValues(alpha: 0.08),
              border: Border.all(
                color: const Color(0xFF6C63FF).withValues(alpha: 0.25),
              ),
              padding: const EdgeInsets.all(14),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      const Icon(Icons.shield_outlined,
                          color: Color(0xFF6C63FF), size: 20),
                      const CustomSizedBox(width: 8),
                      const CustomText(
                        'Form Validation Suite',
                        variant: CustomTextVariant.heading,
                        fontSize: 15,
                        color: Color(0xFF6C63FF),
                      ),
                    ],
                  ),
                  const CustomSizedBox(height: 6),
                  const CustomText(
                    'Eliminates 50+ lines of regex boilerplate. Switch mode below to see both usage styles:',
                    fontSize: 12,
                    color: Colors.black87,
                  ),
                  const CustomSizedBox(height: 10),
                  // Toggle Mode Bar
                  CustomContainer(
                    radius: 8,
                    color: Colors.white,
                    padding:
                        const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
                    border: Border.all(color: Colors.grey.shade300),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Expanded(
                          child: CustomText(
                            _useSimpleValidators
                                ? '1. Simple Way (FormValidators Class)'
                                : '2. Custom Way (String? Extension)',
                            fontSize: 12,
                            fontWeight: FontWeight.w600,
                            color: const Color(0xFF6C63FF),
                          ),
                        ),
                        Switch(
                          value: _useSimpleValidators,
                          activeTrackColor: const Color(0xFF6C63FF),
                          onChanged: (val) {
                            setState(() => _useSimpleValidators = val);
                          },
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),

            const CustomSizedBox(height: 14),

            // Code Syntax Snippet Preview Card
            CustomContainer(
              radius: 8,
              color: Colors.grey.shade900,
              padding: const EdgeInsets.all(12),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      const Icon(Icons.code,
                          color: Colors.greenAccent, size: 16),
                      const CustomSizedBox(width: 6),
                      CustomText(
                        _useSimpleValidators
                            ? 'Simple Way: Pass ready-made validator directly'
                            : 'Chainable Way: Null-safe ?? chaining',
                        color: Colors.greenAccent,
                        fontSize: 12,
                        fontWeight: FontWeight.w600,
                      ),
                    ],
                  ),
                  const CustomSizedBox(height: 6),
                  CustomText(
                    _useSimpleValidators
                        ? 'validator: FormValidators.email()\nvalidator: FormValidators.password(minLength: 8)\nvalidator: FormValidators.cnic()'
                        : 'validator: (val) => val.validateRequired(\'Required\')\n    ?? val.validateEmail(\'Invalid email\')',
                    color: Colors.white70,
                    fontSize: 11,
                  ),
                ],
              ),
            ),

            const CustomSizedBox(height: 16),

            // 1. Email Field
            CustomTextField(
              controller: _emailController,
              labelText: 'Email Address',
              hintText: 'name@example.com',
              keyboardType: TextInputType.emailAddress,
              prefixIcon: const Icon(Icons.email_outlined),
              validator: _useSimpleValidators
                  ? FormValidators.email()
                  : (val) =>
                      val.validateRequired('Email is required') ??
                      val.validateEmail(
                          invalidMessage: 'Please enter a valid email'),
            ),

            const CustomSizedBox(height: 12),

            // 2. Password Field (with eye toggle)
            CustomTextField.password(
              controller: _passwordController,
              labelText: 'Password',
              hintText: 'Min 8 chars, 1 digit, 1 special char',
              validator: _useSimpleValidators
                  ? FormValidators.password(minLength: 8)
                  : (val) =>
                      val.validateRequired('Password is required') ??
                      val.validatePassword(minLength: 8),
            ),

            const CustomSizedBox(height: 12),

            // 3. Confirm Password Field (with eye toggle)
            CustomTextField.password(
              controller: _confirmPasswordController,
              labelText: 'Confirm Password',
              hintText: 'Re-enter your password',
              prefixIcon: const Icon(Icons.lock_reset),
              validator: _useSimpleValidators
                  ? FormValidators.confirmPassword(
                      () => _passwordController.text,
                      'Passwords do not match',
                    )
                  : (val) =>
                      val.validateRequired('Please confirm password') ??
                      val.validateMatch(
                        _passwordController.text,
                        'Passwords do not match',
                      ),
            ),

            const CustomSizedBox(height: 12),

            // 4. CNIC / National ID Field (with Country Length Switcher)
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                const CustomText(
                  'National ID Format (Any Country):',
                  fontSize: 12,
                  fontWeight: FontWeight.w600,
                ),
                CustomText(
                  '$_selectedIdLength Digits',
                  fontSize: 11,
                  color: const Color(0xFF6C63FF),
                  fontWeight: FontWeight.bold,
                ),
              ],
            ),
            const CustomSizedBox(height: 6),
            Wrap(
              spacing: 6,
              children: [
                ChoiceChip(
                  label: const Text('Pakistan (13)',
                      style: TextStyle(fontSize: 11)),
                  selected: _selectedIdLength == 13,
                  selectedColor: const Color(0xFF6C63FF).withValues(alpha: 0.2),
                  onSelected: (selected) {
                    if (selected) {
                      setState(() {
                        _selectedIdLength = 13;
                        _selectedIdMask = '#####-#######-#';
                        _selectedIdHint = '35202-1234567-1 (13 digits)';
                        _cnicController.clear();
                      });
                    }
                  },
                ),
                ChoiceChip(
                  label:
                      const Text('11 Digits', style: TextStyle(fontSize: 11)),
                  selected: _selectedIdLength == 11,
                  selectedColor: const Color(0xFF6C63FF).withValues(alpha: 0.2),
                  onSelected: (selected) {
                    if (selected) {
                      setState(() {
                        _selectedIdLength = 11;
                        _selectedIdMask = '###-####-####';
                        _selectedIdHint = '123-4567-8901 (11 digits)';
                        _cnicController.clear();
                      });
                    }
                  },
                ),
                ChoiceChip(
                  label: const Text('9 Digits (US SSN)',
                      style: TextStyle(fontSize: 11)),
                  selected: _selectedIdLength == 9,
                  selectedColor: const Color(0xFF6C63FF).withValues(alpha: 0.2),
                  onSelected: (selected) {
                    if (selected) {
                      setState(() {
                        _selectedIdLength = 9;
                        _selectedIdMask = '###-##-####';
                        _selectedIdHint = '123-45-6789 (9 digits)';
                        _cnicController.clear();
                      });
                    }
                  },
                ),
              ],
            ),
            const CustomSizedBox(height: 8),
            CustomTextField(
              key: ValueKey(_selectedIdMask),
              controller: _cnicController,
              labelText: 'National ID / CNIC ($_selectedIdLength digits)',
              hintText: _selectedIdHint,
              mask: _selectedIdMask,
              prefixIcon: const Icon(Icons.badge_outlined),
              validator: _useSimpleValidators
                  ? FormValidators.nationalId(length: _selectedIdLength)
                  : (val) =>
                      val.validateRequired('National ID is required') ??
                      val.validateNationalId(length: _selectedIdLength),
            ),

            const CustomSizedBox(height: 12),

            // 5. Phone Field
            CustomTextField(
              controller: _phoneController,
              labelText: 'Phone Number',
              hintText: '+92 300 1234567',
              keyboardType: TextInputType.phone,
              prefixIcon: const Icon(Icons.phone_outlined),
              validator: _useSimpleValidators
                  ? FormValidators.phone()
                  : (val) =>
                      val.validateRequired('Phone is required') ??
                      val.validatePhone(),
            ),

            const CustomSizedBox(height: 16),

            // Submit / Validate Button
            Row(
              children: [
                Expanded(
                  flex: 3,
                  child: CustomButton.primary(
                    title: 'Validate Form',
                    icon: Icons.check_circle_outline,
                    onPressed: () {
                      if (_formKey.currentState!.validate()) {
                        context.showSuccessDialog(
                          title: 'Validation Passed! 🎉',
                          message:
                              'All fields are 100% valid using ${_useSimpleValidators ? "FormValidators" : "Chainable Extensions"}!',
                        );
                      } else {
                        context.showCustomSnackBar(
                          'Please fix the highlighted errors',
                          backgroundColor: Colors.red.shade700,
                          icon: Icons.error_outline,
                        );
                      }
                    },
                  ),
                ),
                const CustomSizedBox(width: 8),
                Expanded(
                  flex: 2,
                  child: CustomButton.outlined(
                    title: 'Reset',
                    icon: Icons.clear_all,
                    onPressed: () {
                      _formKey.currentState?.reset();
                      _emailController.clear();
                      _passwordController.clear();
                      _confirmPasswordController.clear();
                      _cnicController.clear();
                      _phoneController.clear();
                      context.hideKeyboard();
                    },
                  ),
                ),
              ],
            ),

            const CustomSizedBox(height: 20),
            const Divider(),
            const CustomSizedBox(height: 14),

            // ─── KEYBOARD & THEME SHORTCUTS ───
            const CustomText(
              'Keyboard & Theme Shortcuts',
              variant: CustomTextVariant.heading,
              fontSize: 16,
            ),
            const CustomSizedBox(height: 6),
            const CustomText(
              'Quick access helpers directly available on BuildContext:',
              fontSize: 12,
              color: Colors.grey,
            ),
            const CustomSizedBox(height: 12),

            // Live Badges Row
            Row(
              children: [
                Expanded(
                  child: CustomContainer(
                    radius: 8,
                    padding: const EdgeInsets.all(10),
                    color: Colors.grey.shade100,
                    border: Border.all(color: Colors.grey.shade300),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        const CustomText('context.isKeyboardOpen',
                            fontSize: 10, color: Colors.grey),
                        const CustomSizedBox(height: 4),
                        Row(
                          children: [
                            Icon(
                              context.isKeyboardOpen
                                  ? Icons.check_circle
                                  : Icons.cancel_outlined,
                              size: 14,
                              color: context.isKeyboardOpen
                                  ? Colors.green
                                  : Colors.grey,
                            ),
                            const CustomSizedBox(width: 4),
                            CustomText(
                              context.isKeyboardOpen ? 'Open' : 'Closed',
                              fontWeight: FontWeight.bold,
                              fontSize: 12,
                            ),
                          ],
                        ),
                      ],
                    ),
                  ),
                ),
                const CustomSizedBox(width: 8),
                Expanded(
                  child: CustomContainer(
                    radius: 8,
                    padding: const EdgeInsets.all(10),
                    color: Colors.grey.shade100,
                    border: Border.all(color: Colors.grey.shade300),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        const CustomText('context.isDarkMode',
                            fontSize: 10, color: Colors.grey),
                        const CustomSizedBox(height: 4),
                        Row(
                          children: [
                            Icon(
                              context.isDarkMode
                                  ? Icons.dark_mode
                                  : Icons.light_mode,
                              size: 14,
                              color: Colors.amber.shade700,
                            ),
                            const CustomSizedBox(width: 4),
                            CustomText(
                              context.isDarkMode ? 'Dark' : 'Light',
                              fontWeight: FontWeight.bold,
                              fontSize: 12,
                            ),
                          ],
                        ),
                      ],
                    ),
                  ),
                ),
                const CustomSizedBox(width: 8),
                Expanded(
                  child: CustomContainer(
                    radius: 8,
                    padding: const EdgeInsets.all(10),
                    color: Colors.grey.shade100,
                    border: Border.all(color: Colors.grey.shade300),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        const CustomText('context.primaryColor',
                            fontSize: 10, color: Colors.grey),
                        const CustomSizedBox(height: 4),
                        Row(
                          children: [
                            Container(
                              width: 12,
                              height: 12,
                              decoration: BoxDecoration(
                                color: context.primaryColor,
                                shape: BoxShape.circle,
                              ),
                            ),
                            const CustomSizedBox(width: 4),
                            const CustomText(
                              'Active',
                              fontWeight: FontWeight.bold,
                              fontSize: 12,
                            ),
                          ],
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),

            const CustomSizedBox(height: 12),

            // Hide Keyboard Action Button
            CustomButton.outlined(
              title: 'Dismiss Keyboard (context.hideKeyboard())',
              icon: Icons.keyboard_hide_outlined,
              onPressed: () {
                context.hideKeyboard();
                context.showCustomSnackBar('context.hideKeyboard() called!');
              },
            ),

            const SizedBox(height: 24),
          ],
        ),
      ),
    );
  }

  // ══════════════════════════════════════════════════════════════════════════
  // TAB 3: PICKERS & MEDIA (Date, Time, Range, Image Preview)
  // ══════════════════════════════════════════════════════════════════════════
  Widget _buildPickersTab() {
    return SingleChildScrollView(
      padding: const EdgeInsets.all(20),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // ─── 1. Date Picker Field ───
          CustomText(
            '1. CustomDatePickerField',
            fontSize: 14,
            variant: CustomTextVariant.heading,
          ),
          CustomGap(height: 16),
          CustomDatePickerField(
            selectedDate: _selectedDate,
            labelText: 'Selected Date',
            dateFormat: 'dd/MM/yyyy',
            onDateSelected: (date) {
              setState(() => _selectedDate = date);
              context
                  .showCustomSnackBar('Date chosen: ${date.toDisplayDate()}');
            },
          ),

          CustomGap(height: 12),
          const Divider(),
          CustomGap(height: 12),

          // ─── 2. Time Picker Field ───
          CustomText(
            '2. CustomTimePickerField',
            fontSize: 14,
            variant: CustomTextVariant.heading,
          ),
          CustomGap(height: 12),
          CustomTimePickerField(
            selectedTime: _selectedTime,
            labelText: 'Selected Time',
            timeFormat: 'hh:mm a',
            onTimeSelected: (time) {
              setState(() => _selectedTime = time);
              context
                  .showCustomSnackBar('Time chosen: ${time.formatPattern()}');
            },
          ),
          CustomGap(height: 12),
          const Divider(),
          CustomGap(height: 12),

          // ─── 3. Date Range Picker ───
          CustomText(
            '3. CustomDateRangePicker',
            fontSize: 14,
            variant: CustomTextVariant.heading,
          ),
          CustomGap(height: 12),
          CustomDateRangePicker(
            startDate: _startDate,
            endDate: _endDate,
            labelText: 'Booking Date Range',
            onRangeSelected: (start, end) {
              setState(() {
                _startDate = start;
                _endDate = end;
              });
              context.showCustomSnackBar(
                'Range: ${start?.toDisplayDate()} - ${end?.toDisplayDate()}',
              );
            },
          ),

          CustomGap(height: 12),
          const Divider(),
          CustomGap(height: 12),

          // ─── 4. Image Preview ───
          CustomText(
            '4. CustomImagePreview & Zoom Modal',
            fontSize: 14,
            variant: CustomTextVariant.heading,
          ),
          CustomGap(height: 8),
          Row(
            children: [
              CustomImagePreview(
                base64Image: _sampleBase64,
                thumbWidth: 120,
                thumbHeight: 120,
                label: 'Sample Thumbnail',
              ),
              CustomGap(width: 20),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    CustomText(
                        'Tap the thumbnail to test full-screen zoom, pan, and reset controls.',
                        fontSize: 14,
                        color: Colors.grey.shade700),
                    CustomGap(height: 8),
                    CustomText('Supports base64 strings and hero transitions.',
                        fontSize: 14, color: Colors.grey.shade700),
                  ],
                ),
              ),
            ],
          ),

          CustomGap(height: 24),
          const Divider(),
          CustomGap(height: 16),
        ],
      ),
    );
  }

  // ══════════════════════════════════════════════════════════════════════════
  // TAB 3: DIALOGS & ALERTS (Success, Error, Confirm, Snackbars)
  // ══════════════════════════════════════════════════════════════════════════
  Widget _buildDialogsTab() {
    return SingleChildScrollView(
      padding: const EdgeInsets.all(20),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          CustomText(
            '1. Animated Context Dialogs',
            fontSize: 14,
            variant: CustomTextVariant.heading,
          ),
          CustomGap(height: 8),
          CustomButton.primary(
            title: 'Show Success Dialog',
            icon: Icons.check_circle_outline,
            color: Colors.green.shade700,
            onPressed: () {
              context.showSuccessDialog(
                title: 'Order Confirmed',
                message:
                    'Your order #84920 has been placed and confirmed successfully!',
              );
            },
          ),
          CustomGap(height: 8),
          CustomButton.primary(
            title: 'Show Error Dialog',
            icon: Icons.error_outline,
            color: Colors.red.shade700,
            onPressed: () {
              context.showErrorDialog(
                title: 'Payment Failed',
                message:
                    'We were unable to process your card. Please try again.',
              );
            },
          ),
          CustomGap(height: 8),
          CustomButton.primary(
            title: 'Show Warning Dialog',
            icon: Icons.warning_amber_outlined,
            color: Colors.orange.shade800,
            onPressed: () {
              context.showWarningDialog(
                title: 'Storage Low',
                message: 'Your device has less than 500 MB remaining space.',
              );
            },
          ),
          CustomGap(height: 8),
          CustomButton.outlined(
            title: 'Show Confirm Dialog',
            icon: Icons.help_outline,
            onPressed: () {
              context.showConfirmDialog(
                title: 'Delete Account?',
                message: 'This will permanently remove all your data. Proceed?',
                isDanger: true,
                confirmText: 'Delete',
                cancelText: 'Cancel',
                onConfirm: () {
                  context.showCustomSnackBar('Item deleted successfully.');
                },
              );
            },
          ),

          CustomGap(height: 12),
          const Divider(),
          CustomGap(height: 12),

          // ─── Floating Snackbars ───
          CustomText(
            '2. Custom Floating SnackBars',
            fontSize: 14,
            variant: CustomTextVariant.heading,
          ),
          CustomGap(height: 8),
          CustomButton(
            title: 'Show Standard SnackBar',
            icon: Icons.chat_bubble_outline,
            onPressed: () {
              context.showCustomSnackBar(
                'This is a modern floating CustomSnackBar notification!',
              );
            },
          ),
          CustomGap(height: 8),
          CustomButton(
            title: 'Show Success SnackBar',
            icon: Icons.check,
            color: Colors.green.shade700,
            onPressed: () {
              CustomSnackBar.showSuccess(
                context,
                'File uploaded successfully!',
              );
            },
          ),
          CustomGap(height: 8),
          CustomButton(
            title: 'Show Error SnackBar',
            icon: Icons.close,
            color: Colors.red.shade700,
            onPressed: () {
              CustomSnackBar.showError(
                context,
                'Connection lost. Please reconnect.',
              );
            },
          ),
          CustomGap(height: 8),
          CustomButton(
            title: 'Show Warning SnackBar',
            icon: Icons.warning_amber,
            color: Colors.orange.shade800,
            onPressed: () {
              CustomSnackBar.showWarning(
                context,
                'Unsaved changes may be lost.',
              );
            },
          ),
          CustomGap(height: 8),
        ],
      ),
    );
  }

  // ══════════════════════════════════════════════════════════════════════════
  // TAB 4: COUNTRIES & CITIES
  // ══════════════════════════════════════════════════════════════
  Widget _buildCountryTab() {
    return SingleChildScrollView(
      padding: const EdgeInsets.all(20),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          CountryDropdown(
            selectedCountry: _selectedCountry,
            showPrefixIcon: false,
            onChanged: (country) {
              setState(() {
                _selectedCountry = country;
                _selectedCity = null;
              });
            },
          ),
          CustomGap(height: 10),
          CityDropdown(
            country: _selectedCountry,
            selectedCity: _selectedCity,
            showPrefixIcon: false,
            onChanged: (city) {
              setState(() => _selectedCity = city);
            },
          ),
          CustomGap(height: 10),
          CountryPhoneField(
            selectedCountry: _selectedCountry,
            onPhoneChanged: (fullPhone, rawNumber, dialCode) {
              setState(() => _phoneNumber = fullPhone);
            },
          ),
          CustomGap(height: 20),
          if (_selectedCountry != null || _selectedCity != null) ...[
            CustomContainer(
              w: 100,
              padding: const EdgeInsets.all(16),
              radius: 12,
              color: Colors.blue.withValues(alpha: 0.08),
              border: Border.all(color: Colors.blue.withValues(alpha: 0.2)),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  CustomText('Selection Details:',
                      fontSize: 16, fontWeight: FontWeight.bold),
                  8.h,
                  if (_selectedCountry != null)
                    CustomText(
                        'Country: ${_selectedCountry!.flag} ${_selectedCountry!.name} (${_selectedCountry!.dialCode})',
                        fontSize: 14,
                        color: Colors.grey.shade700),
                  if (_selectedCity != null)
                    CustomText('City: $_selectedCity',
                        fontSize: 14, color: Colors.grey.shade700),
                  if (_phoneNumber.isNotEmpty)
                    CustomText('Phone: $_phoneNumber',
                        fontSize: 14, color: Colors.grey.shade700),
                  CustomGap(height: 8),
                  if (_selectedCity != null)
                    CustomText(
                      'Is "$_selectedCity" in Pakistan? ${_selectedCity!.isCityOf('PK')}',
                      fontSize: 14,
                      color: Colors.indigo,
                    ),
                ],
              ),
            ),
            CustomGap(height: 20),
          ],
        ],
      ),
    );
  }

  // ══════════════════════════════════════════════════════════════════════════
  // TAB 5: PROFESSIONAL DATA TABLE
  // ══════════════════════════════════════════════════════════════════════════
  Widget _buildDataTableTab() {
    final columns = [
      DataTableColumn(label: 'ID', field: 'id', sortable: true),
      DataTableColumn(label: 'Name', field: 'name', sortable: true),
      DataTableColumn(label: 'Role', field: 'role', sortable: true),
      DataTableColumn(label: 'Country', field: 'country'),
      DataTableColumn(label: 'Joined', field: 'joined', isDate: true),
      DataTableColumn(label: 'Active', field: 'active'),
    ];

    final data = [
      {
        'id': '101',
        'name': 'Ali Khan',
        'role': 'Senior Flutter Dev',
        'country': '🇵🇰 Pakistan',
        'joined': '2023-01-15',
        'active': true,
      },
      {
        'id': '102',
        'name': 'Sara Ahmed',
        'role': 'UI/UX Designer',
        'country': '🇦🇪 UAE',
        'joined': '2023-06-20',
        'active': true,
      },
      {
        'id': '103',
        'name': 'John Doe',
        'role': 'Backend Engineer',
        'country': '🇺🇸 USA',
        'joined': '2024-02-10',
        'active': false,
      },
      {
        'id': '104',
        'name': 'Fatima Noor',
        'role': 'Product Manager',
        'country': '🇬🇧 UK',
        'joined': '2024-05-01',
        'active': true,
      },
    ];

    return Padding(
      padding: const EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          CustomText(
            'ProfessionalDataTable Demo',
            fontSize: 20,
            fontWeight: FontWeight.bold,
          ),
          CustomGap(height: 8),
          Expanded(
            child: ProfessionalDataTable(
              columns: columns,
              data: data,
              buildActions: (row) => [
                IconButton(
                  icon: const Icon(Icons.edit, size: 20, color: Colors.blue),
                  tooltip: 'Edit ${row['name']}',
                  onPressed: () {
                    context.showCustomSnackBar('Editing ${row['name']}');
                  },
                ),
                IconButton(
                  icon: const Icon(Icons.delete_outline,
                      size: 20, color: Colors.red),
                  tooltip: 'Delete ${row['name']}',
                  onPressed: () {
                    context.showConfirmDialog(
                      title: 'Delete ${row['name']}?',
                      message: 'Are you sure you want to delete this row?',
                      isDanger: true,
                      onConfirm: () {
                        context.showCustomSnackBar('${row['name']} deleted.');
                      },
                    );
                  },
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
3
likes
160
points
235
downloads
screenshot

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter toolkit featuring country & city pickers, form validators, universal auto-masking, custom UI widgets, and daily developer extensions.

Homepage
Repository (GitHub)
View/report issues

Topics

#country #validation #dropdown #extensions #widget

License

MIT (license)

Dependencies

cupertino_icons, flutter, intl

More

Packages that depend on super_daily_extensions