save_points_extensions_utils 1.3.0 copy "save_points_extensions_utils: ^1.3.0" to clipboard
save_points_extensions_utils: ^1.3.0 copied to clipboard

Extensions and reusable widgets. Provides 100+ widget extensions, 40+ animated effects, 40+ pre-built UI components, data type extensions, form validators, spacing utilities, and more. Zero dependenci [...]

Save Points Extensions #

A comprehensive Flutter library of extensions and reusable widgets designed to enhance developer productivity and code quality. This library provides a collection of well-organized, type-safe extensions and widgets following Flutter best practices.

A powerful, modular, zero-dependency Extensions library for Flutter

Dart Flutter License

Pure DartZero Dependencies100+ Extensions40+ AnimationsFully ModularProduction Ready

🚀 Live DemoFeaturesInstallationQuick StartDocumentationExamples

Image

Image

📋 Table of Contents #


✨ Features #

Category Description
100+ Widget Extensions Streamline widget composition with chainable methods (padding, margin, center, clip, transform, gestures, and more)
40+ Widget Animation Effects Easy-to-use animation extensions (fadeIn, scaleIn, slideIn, bounce, pulse, shake, shimmer, flip, glow, and more)
35+ Pre-built UI Components Production-ready reusable widgets (avatars, cards, buttons, loaders, navigation, and more)
Comprehensive Data Type Extensions Enhance String, Number, List, Map, Color, Context, and Animation with 50+ utility methods
Professional Code Quality Fully documented with examples, type-safe, null-safe, and following Flutter best practices
Form Validation Comprehensive validators for common use cases (email, phone, URL, required, length, etc.)
Utility Helpers Spacing constants, app constants, debounce/throttle helpers, and reusable utilities
Zero Dependencies Pure Flutter/Dart, no external dependencies
Well Documented Every extension includes comprehensive documentation with usage examples

📦 Installation #

Add this to your pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  save_points_extensions_utils: ^1.3.0

Then import the extensions:

// Option 1: Import everything from main library
import 'package:save_points_extensions_utils/save_points_extensions_utils.dart';

// Option 2: Import specific parts
import 'package:save_points_extensions_utils/extensions/logics/extensions.dart';
import 'package:save_points_extensions_utils/utils/utils.dart';

⚠️ Avoiding Conflicts with Other Packages #

If you're using multiple packages that might have naming conflicts (e.g., save_points_extensions_utils and save_points_chart), here are strategies to avoid conflicts:

import 'package:save_points_extensions_utils/save_points_extensions_utils.dart' as utils;
import 'package:save_points_chart/save_points_chart.dart' as chart;

// Use with prefix
utils.Spacing.md;
utils.Validators.email('test@example.com');
chart.ChartConfig();

Strategy 2: Use Explicit Imports with show #

// Import only what you need
import 'package:save_points_extensions_utils/utils/utils.dart' 
  show Spacing, Validators, AppConstants;
import 'package:save_points_chart/chart_utils.dart' 
  show ChartConfig, ChartType;

Strategy 3: Use hide to Exclude Conflicting Names #

import 'package:save_points_extensions_utils/utils/utils.dart' 
  hide SpacingConfig; // Hide if it conflicts
import 'package:save_points_chart/chart_utils.dart';

Strategy 4: Import Extensions Separately #

Extensions on built-in types (String, List, Widget, etc.) won't conflict if they have different method names. If they do conflict, use prefixes:

import 'package:save_points_extensions_utils/save_points_extensions_utils.dart' as utils;
import 'package:save_points_chart/save_points_chart.dart' as chart;

// Extensions work normally
'hello'.capitalize(); // Uses utils extension

// If methods conflict, use explicit extension
utils.StringExtensions('hello').capitalize();

Common Conflict Scenarios #

  1. Utility Classes: Spacing, Validators, AppConstants - Use prefixes
  2. Config Classes: SpacingConfig, ValidatorConfig - Use prefixes or show/hide
  3. Extension Methods: Usually fine unless same method name - Use prefixes if needed
  4. Static Methods: Use prefixes or explicit class names

Best Practice #

For projects using multiple save_points_* packages, always use library prefixes:

import 'package:save_points_extensions_utils/save_points_extensions_utils.dart' as utils;
import 'package:save_points_chart/save_points_chart.dart' as chart;
import 'package:save_points_other/save_points_other.dart' as other;

// Clear and conflict-free
utils.Spacing.md;
chart.ChartConfig();
other.OtherUtility();

📖 For more details, see:

  • Conflict Prevention Guide - Detailed guide on avoiding conflicts
  • Best Practices - Comprehensive best practices guide

🚀 Quick Start #

Using Widget Extensions #

Chain multiple extensions together for clean, readable code:

import 'package:save_points_extensions_utils/extensions/extensions.dart';

// Chain widget modifications
const Text('Chained Extensions')
  .padding(all: 20)
  .center()
  .clipRRect(borderRadius: 16)
  .decoratedBox(
    color: context.colorScheme.primaryContainer,
    borderRadius: BorderRadius.circular(16),
    boxShadow: [
      BoxShadow(
        color: context.colorScheme.primary.withOpacity(0.3),
        blurRadius: 8,
        offset: Offset(0, 4),
      ),
    ],
  )
  .onTap(() => print('Tapped!'))
  .tooltip('Tap me!');

// Transform widgets
const Icon(Icons.star, size: 48)
  .rotate(0.2)
  .scale(1.5)
  .translate(x: 10, y: 5);

// Clip widgets
Container(
  width: 100,
  height: 100,
  color: Colors.blue,
)
  .clipRRect(borderRadius: 16)
  .clipOval()
  .onTap(() => print('Tapped'));

Using Context Extensions #

Easy access to theme, media query, and navigation:

import 'package:save_points_extensions_utils/extensions/extensions.dart';

// Theme access
context.colorScheme.primary
context.textTheme.headlineLarge
context.isDarkMode
context.isLightMode

// Screen dimensions
context.screenWidth
context.screenHeight
context.screenSize
context.isMobile
context.isTablet
context.isDesktop

// Navigation helpers
context.push(MyPage());
context.pop();
context.showMessage('Hello!'); // Show feedback message
context.hideKeyboard();

Using Data Extensions #

String Extensions

// Text manipulation
'hello world'.capitalize()           // "Hello world"
'hello world'.capitalizeWords()       // "Hello World"
'very long text'.truncate(10)        // "very long..."
'hello world'.removeWhitespace()     // "helloworld"
'hello world'.reverse()               // "dlrow olleh"
'hello world'.toSlug()                // "hello-world"

// Validation
'email@test.com'.isValidEmail        // true
'https://example.com'.isValidUrl      // true
'+1234567890'.isValidPhone           // true
'12345'.isNumeric                     // true
'Hello'.isAlpha                       // true
'Hello123'.isAlphanumeric             // true

// Utilities
'hello world'.startsWithAny(['he', 'hi'])  // true
'hello world'.endsWithAny(['ld', 'la'])    // true
'hello world'.findAll(RegExp(r'\w+'))      // ['hello', 'world']

Number Extensions

// Formatting
42.format(prefix: 'Count: ')              // "Count: 42"
1234567.formatWithSeparator()             // "1,234,567"
1234.formatCurrency()                     // "$1,234.00"
1500000.toHumanReadable()                 // "1.5M"

// Validation
42.isEven                                 // true
42.isOdd                                  // false
5.isPositive                              // true
(-5).isNegative                           // true
5.isBetween(1, 10)                        // true

// Duration helpers
60.seconds                                // Duration(seconds: 60)
5.minutes                                 // Duration(minutes: 5)
2.hours                                   // Duration(hours: 2)
7.days                                    // Duration(days: 7)

// Ranges
1.rangeTo(5)                              // [1, 2, 3, 4]
1.rangeToInclusive(5)                     // [1, 2, 3, 4, 5]

List Extensions

// Safe access
list.firstOrNull                          // First element or null
list.lastOrNull                           // Last element or null
list.elementAtOrNull(5)                   // Element at index or null
list.elementAtOrDefault(5, defaultValue)  // Element or default

// Manipulation
[1, 2, 2, 3].distinct                     // [1, 2, 3]
list.distinctBy((item) => item.id)        // Remove duplicates by key
list.chunk(3)                             // Split into chunks of 3
list.shuffled                             // New shuffled list

// Querying
list.firstWhereOrNull((x) => x > 3)       // First matching or null
list.lastWhereOrNull((x) => x > 3)        // Last matching or null
list.any((x) => x > 5)                    // true if any matches
list.all((x) => x > 0)                    // true if all match

// Aggregation
list.sum((x) => x.value)                  // Sum of values
list.average((x) => x.value)              // Average of values
list.maxBy((x) => x.value)                 // Max element
list.minBy((x) => x.value)                 // Min element

// Grouping
list.groupBy((item) => item.category)      // Map<K, List<T>>

// Slicing
list.drop(2)                              // Remove first 2
list.dropLast(2)                          // Remove last 2
list.take(3)                              // Take first 3
list.takeLast(3)                          // Take last 3

Map Extensions

// Safe access
map.getOrNull('key')                      // Value or null
map.getOrDefault('key', defaultValue)     // Value or default
map.getOrPut('key', () => defaultValue)   // Value or compute and store

// Transformation
map.mapKeys((k) => k.toUpperCase())       // Transform keys
map.mapValues((v) => v * 2)               // Transform values
map.filter((k, v) => v > 10)              // Filter entries

// Utilities
map.firstEntry                            // First entry or null
map.lastEntry                             // Last entry or null
map.merge(otherMap)                      // Merge maps
map.mergeWith(otherMap, (a, b) => a + b)  // Merge with function
map.invert()                              // Swap keys and values
map.sortedByKey()                         // Sort by keys
map.sortedByValue()                       // Sort by values

Color Extensions

// Manipulation
color.darken(0.2)                         // Darker color
color.lighten(0.2)                        // Lighter color
color.saturate(0.3)                       // More saturated
color.desaturate(0.3)                     // Less saturated
color.blend(otherColor, 0.5)              // Blend colors
color.adjustBrightness(0.2)               // Adjust brightness
color.adjustHue(120)                      // Shift hue
color.complementary                       // Complementary color

// Conversion
color.hexString                           // "#FF2196F3"
color.hexStringNoAlpha                    // "#2196F3"
color.toRgb()                             // {'r': 255, 'g': 0, 'b': 0}
color.toHsl()                             // {'h': 0.0, 's': 1.0, 'l': 0.5}

// Utilities
color.isDark                              // true if dark
color.isLight                             // true if light
color.contrastingColor                    // Black or white for contrast

// Static factories
ColorExtensions.fromHex('#FF0000')        // From hex string
ColorExtensions.fromRgb(255, 0, 0)        // From RGB
ColorExtensions.fromHsl(0, 1.0, 0.5)      // From HSL

Animation Extensions

// Animation status
animation.isCompleted                     // true if completed
animation.isDismissed                     // true if dismissed
animation.isForward                       // true if forward
animation.isReverse                       // true if reverse
animation.isAnimating                     // true if animating
animation.clampedValue                    // Value clamped 0.0-1.0
animation.reversedValue                   // 1.0 - value

// Controller utilities
controller.toggle()                       // Toggle animation
controller.resetAndForward()              // Reset and forward
controller.resetAndReverse()              // Reset and reverse
controller.isNotAnimating                 // true if not animating

// Tween utilities
tween.reverse                             // Reverse tween
tween.evaluate(0.5)                       // Value at 0.5
tween.lerp(0.5)                           // Value at 0.5

Widget Animation Effects

// Fade animations
Text('Hello').fadeIn()                    // Fade in animation
Text('Hello').fadeOut()                   // Fade out animation
Text('Hello').fade(opacity: 0.5)          // Animated opacity

// Scale animations
Icon(Icons.star).scaleIn()                // Scale in with bounce
Icon(Icons.star).scaleOut()               // Scale out animation
Icon(Icons.star).animatedScale(scale: 1.5) // Animated scale

// Slide animations
Card().slideInFromLeft()                  // Slide in from left
Card().slideInFromRight()                 // Slide in from right
Card().slideInFromTop()                   // Slide in from top
Card().slideInFromBottom()                // Slide in from bottom

// Bounce & elastic
Button().bounceIn()                       // Bounce in animation
Button().elasticIn()                      // Elastic scale effect
Icon(Icons.arrow).bounce()                // Continuous bounce

// Rotation
Icon(Icons.settings).animatedRotate(turns: 0.5)  // Animated rotation
Icon(Icons.refresh).spin()                // Continuous spin
Icon(Icons.refresh).spinIn()              // Spin in animation

// Shake (great for error feedback)
TextField().shake()                       // One-time shake
TextField().shakeHorizontal()             // Continuous horizontal shake
TextField().shakeVertical()               // Continuous vertical shake

// Pulse & heartbeat
Icon(Icons.favorite).pulse()              // Continuous pulse
Icon(Icons.favorite).heartbeat()          // Heartbeat effect

// Flip animations
Card().flipHorizontal(isFlipped: true)    // Horizontal flip
Card().flipVertical(isFlipped: true)      // Vertical flip
Card().flipIn()                           // Flip in animation

// Special effects
Container().shimmer()                     // Shimmer loading effect
Image().zoomIn()                          // Zoom in with fade
Image().blurIn()                          // Blur to clear
Icon(Icons.cloud).float()                 // Floating animation
Icon(Icons.star).glow(color: Colors.amber) // Glowing effect
Icon(Icons.bell).swing()                  // Pendulum swing
Icon(Icons.cake).wobble()                 // Wobble rotation

// Fun animations
Text('Boing!').jello()                    // Jello effect
Button().rubberBand()                     // Rubber band stretch

// Hero animation
Image().hero('image-tag')                 // Hero transition wrapper

// Utility animations
Container().animatedSize()                // Animated size changes
Text('Hello').crossFade(key: ValueKey(1)) // Cross-fade switching
Text('Typing...').typing(text: 'Hello')   // Typewriter effect

Using Utilities #

Validators

import 'package:save_points_extensions_utils/utils/utils.dart';

// In form validation
TextFormField(
  validator: (value) => Validators.required(value),
)

TextFormField(
  validator: (value) => Validators.email(value),
)

// Available validators
Validators.required(value)
Validators.email(value)
Validators.phone(value)
Validators.url(value)
Validators.numeric(value)
Validators.minLength(value, 8)
Validators.maxLength(value, 100)
Validators.match(value, otherValue)

Spacing

import 'package:save_points_extensions_utils/utils/utils.dart';

// Constants
Spacing.xs  // 4.0
Spacing.sm  // 8.0
Spacing.md  // 16.0
Spacing.lg  // 24.0
Spacing.xl  // 32.0

// Helpers
Spacing.vertical(16)
Spacing.horizontal(8)
Spacing.all(16)
Spacing.symmetric(horizontal: 8, vertical: 16)
Spacing.only(top: 8, bottom: 16)

Constants

import 'package:save_points_extensions_utils/utils/utils.dart';

AppConstants.defaultPadding
AppConstants.defaultBorderRadius
AppConstants.shortAnimation

Debounce & Throttle

import 'package:save_points_extensions_utils/utils/utils.dart';

final debounce = Debounce(const Duration(milliseconds: 300));
final throttle = Throttle(const Duration(milliseconds: 500));

// Runs once after rapid triggers settle
debounce(() {
  // Your code here
});

// Runs at most once in the given interval
throttle(() {
  // Your code here
});

📚 Available Extensions #

Widget Extensions #

Located in lib/extensions/widgets/:

  • Core Extensions (widget_core_extensions.dart) - padding, margin, center, expanded, flexible, sizedBox, container, opacity, visible, safeArea, decoratedBox
  • Gesture Extensions (widget_gesture_extensions.dart) - onTap, onLongPress, onDoubleTap, inkWell
  • Clip Extensions (widget_clip_extensions.dart) - clipRRect, clipOval, clipRect
  • Transform Extensions (widget_transform_extensions.dart) - rotate, scale, translate, transform
  • Layout Extensions (widget_layout_extensions.dart) - align, positioned, aspectRatio, constrained, fittedBox, fractionallySizedBox
  • Material Extensions (widget_material_extensions.dart) - material, card
  • Animation Effects (widget_animation_extensions.dart) - 40+ animation effects (fadeIn, scaleIn, slideIn, bounce, pulse, shake, shimmer, flip, glow, hero, and more)
  • Scroll Extensions (widget_scroll_extensions.dart) - scrollable
  • Sizing Extensions (widget_sizing_extensions.dart) - intrinsicHeight, intrinsicWidth, unconstrained, limitedBox, overflowBox
  • Semantics Extensions (widget_semantics_extensions.dart) - semantics, tooltip
  • Text Extensions (widget_text_extensions.dart) - TextExtensions.bold, TextExtensions.italic
  • Icon Extensions (widget_icon_extensions.dart) - IconExtensions.themed
  • Image Extensions (widget_image_extensions.dart) - ImageExtensions.networkWithFallback
  • List Extensions (widget_list_extensions.dart) - ListViewExtensions.withPadding, GridViewExtensions.withDefaults
  • Stack Extensions (widget_stack_extensions.dart) - StackExtensions.centered
  • Column/Row Extensions (widget_column_row_extensions.dart) - ColumnExtensions.centered, RowExtensions.centered
  • Wrap Extensions (widget_column_row_extensions.dart) - WrapExtensions.withSpacing

Data Type Extensions #

  • String Extensions (string_extensions.dart) - 30+ methods for text manipulation, validation, and formatting
  • Number Extensions (number_extensions.dart) - Formatting, validation, duration helpers, ranges, and more
  • Duration Extensions (duration_extensions.dart) - Human-readable strings, formatted output
  • List Extensions (list_extensions.dart) - 40+ methods for safe access, manipulation, querying, aggregation, grouping
  • Map Extensions (map_extensions.dart) - Safe access, transformation, filtering, merging, sorting
  • Color Extensions (color_extensions.dart) - Color manipulation, conversion, blending, HSL/RGB conversion
  • Context Extensions (context_extensions.dart) - Theme access, media query, navigation, keyboard, screen size detection
  • Animation Extensions (animation_extensions.dart) - Animation status checks, controller utilities, tween helpers

🛠️ Utilities #

Validators #

Comprehensive form validation utilities:

import 'package:save_points_extensions_utils/utils/utils.dart';

Validators.required(value)
Validators.email(value)
Validators.phone(value)
Validators.url(value)
Validators.numeric(value)
Validators.minLength(value, 8)
Validators.maxLength(value, 100)
Validators.match(value, otherValue)

Spacing #

Consistent spacing constants and helpers:

import 'package:save_points_extensions_utils/utils/utils.dart';

// Constants
Spacing.xs  // 4.0
Spacing.sm  // 8.0
Spacing.md  // 16.0
Spacing.lg  // 24.0
Spacing.xl  // 32.0

// Helpers
Spacing.vertical(16)
Spacing.horizontal(8)
Spacing.all(16)
Spacing.symmetric(horizontal: 8, vertical: 16)
Spacing.only(top: 8, bottom: 16)

Constants #

Application-wide constants:

import 'package:save_points_extensions_utils/utils/utils.dart';

AppConstants.defaultPadding
AppConstants.defaultBorderRadius
AppConstants.shortAnimation

Debounce & Throttle #

Control how frequently callbacks execute to prevent spamming expensive work:

import 'package:save_points_extensions_utils/utils/utils.dart';

final debounce = Debounce(const Duration(milliseconds: 300));
final throttle = Throttle(const Duration(milliseconds: 500));

// Runs once after rapid triggers settle
debounce(() {
  // Your code here
});

// Runs at most once in the given interval
throttle(() {
  // Your code here
});

🎨 Pre-built UI Components #

The library includes 35+ production-ready, customizable UI components organized by category:

Core Components #

Essential building blocks for any Flutter application

import 'package:save_points_extensions_utils/widgets/components/components.dart';

// Avatar with fallback
AvatarWidget(
  imageUrl: 'https://example.com/avatar.jpg',
  fallbackText: 'JD',
  size: 50,
  showStatusIndicator: true,
)

// Custom button with loading state
CustomButton(
  text: 'Submit',
  onPressed: () => submitForm(),
  isLoading: false,
  icon: Icons.send,
)

// Custom text field with validation
CustomTextField(
  label: 'Email',
  hint: 'Enter your email',
  validator: Validators.email,
  prefixIcon: Icons.email,
)

// Custom card with elevation
CustomCard(
  title: 'Card Title',
  subtitle: 'Card description',
  child: Text('Content here'),
  onTap: () => print('Tapped'),
)

// Loading states
LoadingIndicator(size: 40, color: Colors.blue)
ShimmerLoading(width: 200, height: 100)
SkeletonLoader(width: double.infinity, height: 60)

// Empty states
EmptyStateWidget(
  icon: Icons.inbox,
  title: 'No items',
  message: 'Add your first item',
  actionLabel: 'Add Item',
  onAction: () => addItem(),
)

// Expandable card
ExpansionCard(
  title: 'Details',
  children: [Text('Hidden content')],
)

// Rating widget
RatingWidget(
  rating: 4.5,
  maxRating: 5,
  onRatingChanged: (rating) => updateRating(rating),
)

// Progress indicators
ProgressBar(value: 0.7, showPercentage: true)

// Stepper
StepperWidget(
  currentStep: 1,
  steps: ['Step 1', 'Step 2', 'Step 3'],
  onStepTapped: (index) => goToStep(index),
)

// Timeline
TimelineWidget(
  events: [
    TimelineEvent(title: 'Event 1', time: '10:00 AM'),
    TimelineEvent(title: 'Event 2', time: '2:00 PM'),
  ],
)

// Search bar
SearchBarWidget(
  onSearch: (query) => searchItems(query),
  hintText: 'Search...',
)

// Navigation components
NavigationBarWidget(
  currentIndex: 0,
  items: [
    BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
    BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Search'),
  ],
  onTap: (index) => changePage(index),
)

// Carousel
CarouselWidget(
  items: [Image.network('url1'), Image.network('url2')],
  autoPlay: true,
  height: 200,
)

// Breadcrumb navigation
BreadcrumbWidget(
  items: ['Home', 'Products', 'Details'],
  onTap: (index) => navigateToLevel(index),
)

// Menu
MenuWidget(
  items: [
    MenuItem(label: 'Edit', icon: Icons.edit),
    MenuItem(label: 'Delete', icon: Icons.delete),
  ],
  onItemSelected: (item) => handleAction(item),
)

// Segmented control
SegmentedControl(
  segments: ['Option 1', 'Option 2', 'Option 3'],
  selectedIndex: 0,
  onSegmentChanged: (index) => handleChange(index),
)

// Custom chip
CustomChip(
  label: 'Tag',
  onDeleted: () => removeTag(),
  avatar: Icon(Icons.star),
)

// Badge
BadgeWidget(
  child: Icon(Icons.notifications),
  value: '5',
  color: Colors.red,
)

// Notification card
NotificationCard(
  title: 'New Message',
  message: 'You have a new message',
  time: '5 min ago',
  onTap: () => openMessage(),
)

// Info banner
InfoBanner(
  message: 'This is an important message',
  type: BannerType.warning,
  onDismiss: () => dismissBanner(),
)

// Divider with text
DividerWidget(text: 'OR', thickness: 1)

// Tooltip
TooltipWidget(
  message: 'This is a tooltip',
  child: Icon(Icons.info),
)

// Tag widget
TagWidget(
  label: 'Featured',
  color: Colors.orange,
  icon: Icons.star,
)

Available Components #

🔘 Buttons & Actions

Component Description
CustomButton Button with loading states and icons
CopyButton Copy-to-clipboard button widget
FloatingActionButtonWidget Custom FAB with extended options
IconButtonWidget Custom icon button

📝 Form & Input

Component Description
CustomTextField Styled text field with validation
DropdownWidget Custom dropdown selector
SearchBarWidget Search input with filtering
RatingWidget Star rating component
SegmentedControl iOS-style segmented control

📦 Cards & Containers

Component Description
CustomCard Enhanced card with various styles
ExpansionCard Expandable card with content
CustomListTile Enhanced list tile with more options
NotificationCard Notification display card
SectionWrapper Section wrapper for layouts

🏷️ Tags & Badges

Component Description
BadgeWidget Notification and status badges
CustomChip Chip/tag component with delete action
TagWidget Tag/label component

🧭 Navigation

Component Description
NavigationBarWidget Bottom navigation bar
BreadcrumbWidget Navigation breadcrumbs
DrawerWidget Navigation drawer component
TabsWidget Custom tabs component
MenuWidget Menu/popup menu component

⏳ Loading & Progress

Component Description
LoadingIndicator Custom loading spinner
ShimmerLoading Shimmer loading effect
SkeletonLoader Skeleton screen loader
ProgressBar Linear and circular progress
StepperWidget Step-by-step progress indicator

📢 Feedback & Status

Component Description
InfoBanner Information/warning banner
EmptyStateWidget Empty state with icon and CTA
TooltipWidget Custom tooltip component

👤 Display & Media

Component Description
AvatarWidget Customizable avatar with fallback and status indicator
CarouselWidget Image/content carousel with auto-play
TimelineWidget Timeline for events
DividerWidget Divider with optional text

📁 Project Structure #

lib/
├── app/
├── extensions/
│   ├── widgets/
│   │   ├── widget_core_extensions.dart
│   │   ├── widget_gesture_extensions.dart
│   │   ├── widget_clip_extensions.dart
│   │   ├── widget_transform_extensions.dart
│   │   ├── widget_layout_extensions.dart
│   │   ├── widget_material_extensions.dart
│   │   ├── widget_animation_extensions.dart
│   │   ├── widget_scroll_extensions.dart
│   │   ├── widget_sizing_extensions.dart
│   │   ├── widget_semantics_extensions.dart
│   │   ├── widget_text_extensions.dart
│   │   ├── widget_icon_extensions.dart
│   │   ├── widget_image_extensions.dart
│   │   ├── widget_list_extensions.dart
│   │   ├── widget_stack_extensions.dart
│   │   ├── widget_column_row_extensions.dart
│   │   └── widgets.dart
│   ├── animation_extensions.dart
│   ├── color_extensions.dart
│   ├── context_extensions.dart
│   ├── duration_extensions.dart
│   ├── list_extensions.dart
│   ├── map_extensions.dart
│   ├── number_extensions.dart
│   ├── string_extensions.dart
│   ├── widget_extensions.dart
│   └── extensions.dart
├── pages/
├── utils/
│   ├── constants.dart
│   ├── spacing.dart
│   ├── validators.dart
│   ├── debounce.dart
│   ├── helpers.dart
│   ├── url_utils.dart
│   ├── string_formatters.dart
│   └── utils.dart
├── widgets/
│   ├── components/
│   │   ├── avatar_widget.dart
│   │   ├── badge_widget.dart
│   │   ├── breadcrumb_widget.dart
│   │   ├── carousel_widget.dart
│   │   ├── copy_button.dart
│   │   ├── custom_button.dart
│   │   ├── custom_card.dart
│   │   ├── custom_chip.dart
│   │   ├── custom_list_tile.dart
│   │   ├── custom_text_field.dart
│   │   ├── divider_widget.dart
│   │   ├── drawer_widget.dart
│   │   ├── dropdown_widget.dart
│   │   ├── empty_state_widget.dart
│   │   ├── expansion_card.dart
│   │   ├── floating_action_button_widget.dart
│   │   ├── icon_button_widget.dart
│   │   ├── info_banner.dart
│   │   ├── loading_indicator.dart
│   │   ├── menu_widget.dart
│   │   ├── navigation_bar_widget.dart
│   │   ├── notification_card.dart
│   │   ├── progress_bar.dart
│   │   ├── rating_widget.dart
│   │   ├── search_bar_widget.dart
│   │   ├── section_wrapper.dart
│   │   ├── segmented_control.dart
│   │   ├── shimmer_loading.dart
│   │   ├── skeleton_loader.dart
│   │   ├── stepper_widget.dart
│   │   ├── tabs_widget.dart
│   │   ├── tag_widget.dart
│   │   ├── timeline_widget.dart
│   │   ├── tooltip_widget.dart
│   │   └── components.dart
│   └── sections/
│       ├── animation_extensions_examples_section.dart
│       ├── debounce_throttle_section.dart
│       └── widget_extensions_section.dart
└── main.dart

💡 Best Practices #

1. Chaining Extensions #

Extensions can be chained for cleaner, more readable code:

const Text('Hello World')
  .padding(all: 16)
  .margin(all: 12)
  .center()
  .clipRRect(borderRadius: 8)
  .decoratedBox(
    color: Colors.blue,
    borderRadius: BorderRadius.circular(8),
  )
  .onTap(() => print('Tapped!'))
  .tooltip('Click me');

2. Safe State Updates #

Always check if the widget is mounted before updating state:

void _incrementCounter() {
  if (mounted) {
    setState(() {
      _counter++;
    });
  }
}

3. Using Context Extensions #

Leverage context extensions for cleaner code:

// ❌ Verbose approach
Theme.of(context).colorScheme.primary
MediaQuery.of(context).size.width

// ✅ Clean approach with extensions
context.colorScheme.primary
context.screenWidth

4. Const Constructors #

Use const constructors where possible for better performance:

const Text('Hello')
  .padding(all: 16)
  .center();

5. Animation Best Practices #

When using animation extensions, consider performance:

// ✅ Good: Use appropriate duration
Text('Hello').fadeIn(duration: Duration(milliseconds: 300))

// ✅ Good: Combine animations efficiently
Icon(Icons.star)
  .scaleIn()
  .fadeIn()

// ✅ Good: Use shimmer for loading states
Container().shimmer()

6. Responsive Design #

Use context extensions for responsive layouts:

// Responsive padding based on screen size
Container(
  padding: EdgeInsets.all(
    context.isMobile ? 8 : context.isTablet ? 16 : 24
  ),
  child: content,
)

🎯 Examples #

🚀 Try the Live Demo to see all features in action!

See lib/main.dart for a comprehensive demo showcasing:

Category Features
Widget Extensions Chaining, padding, margin, center, clip, transform
Transform Extensions Rotate, scale, translate widgets
Clip Extensions ClipRRect, ClipOval, ClipRect
Data Extensions String, Number, List operations
Color Extensions Darken, lighten, blend, HSL conversion
Gesture Extensions onTap, onLongPress, inkWell
Animation Extensions Hero, clamped/reversed values, curves, controller helpers
Widget Animations 40+ effects: fadeIn, scaleIn, slideIn, bounce, pulse, shake, shimmer, flip, glow
Form Validation Email, phone, URL, required, length validators
Context Extensions Theme access, navigation, screen size detection
Performance Helpers Debounce & throttle utilities
Developer Tools CopyButton for quick code snippets

📝 License #

This project is open source and available under the MIT License for use in your Flutter projects.

🤝 Contributing #

Contributions are welcome! Here's how you can help:

  1. Add new extensions - Propose and implement useful extensions
  2. Improve existing ones - Optimize performance or add features
  3. Fix bugs - Report or fix issues you encounter
  4. Enhance documentation - Improve examples and explanations
  5. Add more examples - Share real-world use cases

Getting Started #

# Clone the repository
git clone https://github.com/your-repo/save_points_extensions.git

# Install dependencies
flutter pub get

# Run the demo app
flutter run

📧 Support #

For issues, questions, or suggestions:

  • 📝 Open an issue in the repository
  • 💬 Start a discussion for feature requests
  • ⭐ Star the repo if you find it useful!

Built with ❤️ for the Flutter community

⬆ Back to Top

2
likes
150
points
180
downloads

Publisher

unverified uploader

Weekly Downloads

Extensions and reusable widgets. Provides 100+ widget extensions, 40+ animated effects, 40+ pre-built UI components, data type extensions, form validators, spacing utilities, and more. Zero dependencies, fully documented, production-ready.

Homepage

Topics

#extensions #widget #utils #validators #spacing

Documentation

API reference

License

MIT (license)

Dependencies

cupertino_icons, flutter

More

Packages that depend on save_points_extensions_utils