essential_flutter

Flutter widgets, components, and services building on essential_dart for accelerated UI development.

Features

  • ConditionalWrapper: Conditionally wrap widgets without nested ternaries.
  • ScrollableBuilder: Handle loading and error states for scrollable widgets.
  • Conditional: Conditionally render widgets based on a boolean condition.
  • Conditional.chain: Chain multiple conditions for complex conditional rendering.

Getting started

Add this to your package's pubspec.yaml file:

dependencies:
  essential_flutter: ^1.1.0

Usage

ConditionalWrapper

Avoid nested ternary operators when conditionally wrapping widgets:

ConditionalWrapper(
  condition: isScrollable,
  wrapper: (child) => SingleChildScrollView(child: child),
  child: MyContent(),
)

ScrollableBuilder

Handle different loading and error states for scrollable widgets like ListView, GridView, etc.

Basic Usage

ScrollableBuilder<String>(
  items: items,
  isLoading: isLoading,
  itemBuilder: (context, items) => ListView.builder(
    itemCount: items.length,
    itemBuilder: (context, index) => ListTile(
      title: Text(items[index]),
    ),
  ),
)

Handling States

You can provide optional builders for specific states. If a builder is not provided, it falls back to a sensible default (usually showing the data or nothing).

ScrollableBuilder<Product>(
  items: products,
  isLoading: isLoading,
  isError: hasError,
  error: errorObject,
  
  // Main content
  itemBuilder: (context, products) => GridView.builder(
    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
    itemCount: products.length,
    itemBuilder: (context, index) => ProductCard(products[index]),
  ),
  
  // Loading when no data
  loadingBuilder: (context) => Center(child: CircularProgressIndicator()),
  
  // Error when no data
  errorBuilder: (context, error) => Center(child: Text('Error: $error')),
  
  // Loading when data exists (e.g. loading more)
  busyItemBuilder: (context, products) => Column(
    children: [
      LinearProgressIndicator(),
      Expanded(
        child: GridView.builder(
          // ... existing grid config
        ),
      ),
    ],
  ),
)

Conditional

Conditionally render widgets based on a boolean condition.

Conditional(
  condition: isLoggedIn,
  onTrue: const Text('Welcome back!'),
  onFalse: OutlinedButton(
    onPressed: () { /* handle login */ },
    child: const Text('Please Log In'),
  ),
)

For more complex scenarios, you can use Conditional.chain:

enum UserStatus {
  loading,
  loggedIn,
  loggedOut,
  error,
}

Conditional.chain(
  [
    (status == UserStatus.loading, widget: const CircularProgressIndicator()),
    (status == UserStatus.loggedIn, widget: const Text('Welcome back!')),
    (status == UserStatus.loggedOut, widget: const Text('Please log in.')),
  ],
  fallback: const Text('An unexpected error occurred.'),
)

Libraries

essential_flutter
Reusable Flutter widgets and utilities.