Skip to main content

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

A comprehensive Flutter toolkit featuring country & city pickers, custom UI widgets, responsive utilities, 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;

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

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

  @override
  void dispose() {
    _tabController.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.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(),
          _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 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: 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
0
points
189
downloads

Publisher

unverified uploader

Weekly Downloads

A comprehensive Flutter toolkit featuring country & city pickers, custom UI widgets, responsive utilities, and daily developer extensions.

Homepage
Repository (GitHub)
View/report issues

Topics

#country #city #dropdown #extensions #widget

License

unknown (license)

Dependencies

cupertino_icons, flutter, intl

More

Packages that depend on super_daily_extensions