Skip to content

feat: add 6 essential mobile-first hooks for modern Flutter apps#72

Merged
wasabeef merged 1 commit intomainfrom
feat-add-essential-hooks
Jun 25, 2025
Merged

feat: add 6 essential mobile-first hooks for modern Flutter apps#72
wasabeef merged 1 commit intomainfrom
feat-add-essential-hooks

Conversation

@wasabeef
Copy link
Copy Markdown
Owner

@wasabeef wasabeef commented Jun 24, 2025

🚀 Overview

This PR introduces 6 essential mobile-first hooks that address common patterns in modern Flutter app development. These hooks provide
production-ready solutions for async operations, form management, infinite scrolling, and keyboard handling.

✨ New Hooks

Async Operations

  • useAsync - Automatically executes async operations with built-in loading, error, and data states
  • useAsyncFn - Manually controlled async operations perfect for user-triggered actions like form submissions

UI Interactions

  • useDebounceFn - Type-safe debounced function execution for search inputs and API calls
  • useKeyboard - Tracks keyboard visibility and dimensions for responsive layouts

Data Management

  • useForm - Comprehensive form state management with validation, dirty tracking, and submission handling
  • useInfiniteScroll - Automatic scroll-based data loading with pagination support

📋 Why These Hooks?

These hooks address the most common mobile app patterns:

  • API Integration: Handle loading states, errors, and data fetching elegantly
  • User Input: Debounce search queries and validate forms with minimal boilerplate
  • Performance: Efficient infinite scrolling and keyboard-aware layouts
  • Developer Experience: Type-safe, well-tested, and thoroughly documented

💡 Usage Examples

// Async data fetching
final userState = useAsync(() => fetchUserData());
if (userState.loading) return CircularProgressIndicator();
if (userState.hasError) return Text('Error: ${userState.error}');
return UserProfile(user: userState.data!);

// Form with validation
final form = useForm({
  'email': useField(validators: [Validators.required(), Validators.email()]),
  'password': useField(validators: [Validators.minLength(8)]),
});

// Infinite scroll
final scroll = useInfiniteScroll(
  loadMore: () async {
    final items = await api.fetchItems(page: currentPage);
    return items.length >= pageSize;
  },
);

📚 Documentation

- Comprehensive DartDoc comments with examples
- Dedicated documentation files in /docs
- Interactive demos for each hook
- Integration with the main demo app

✅ Testing

- 100% test coverage for all new hooks
- Edge cases and error scenarios covered
- Consistent with existing test patterns

🏗️ Architecture

- Followed existing patterns (e.g., useAsyncFn in separate file like other Fn-suffix hooks)
- Extracted shared AsyncState class to avoid duplication
- Maintained backward compatibility (except for the breaking change below)

⚠️ Breaking Changes

- Removed flutter_hooks_testing.dart in favor of inline testing utilities. This file was not part of the public API and was only used
internally for tests.

📝 Checklist

- All tests pass (252 tests passing)
- Documentation added for all public APIs
- Demo examples created
- Code follows existing patterns and conventions
- No linting issues
- README updated with new hooks

@wasabeef wasabeef marked this pull request as ready for review June 24, 2025 10:21
@wasabeef wasabeef force-pushed the feat-add-essential-hooks branch from 0bfb68f to 81835a9 Compare June 25, 2025 01:24
@wasabeef wasabeef force-pushed the feat-add-essential-hooks branch from 81835a9 to 5c5dda3 Compare June 25, 2025 03:21
@wasabeef wasabeef merged commit 46bbe31 into main Jun 25, 2025
2 checks passed
@wasabeef wasabeef deleted the feat-add-essential-hooks branch June 25, 2025 03:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant