pagy 1.4.0
pagy: ^1.4.0 copied to clipboard
A Flutter package for easy pagination with API data fetching, customizable UI, shimmer effects, error handling, and smooth scrolling.
1.4.0 #
✨ Redesigned Controller Helpers API #
Complete overhaul of PagyControllerHelpers with a cleaner, more intuitive API. All old methods are preserved as @Deprecated and delegate to the new implementations — zero breaking changes.
New Methods
| Category | Method | Description |
|---|---|---|
| Adding | add() |
Add single item with InsertPosition enum |
| Adding | addAll() |
Add multiple items with InsertPosition enum |
| Adding | insert() |
Insert at specific index (safe) |
| Updating | update() |
Update item at index, returns success bool |
| Updating | updateWhere() |
Update matching items with where/update pattern, returns count |
| Removing | remove() |
Remove matching items with named where: param, returns count |
| Removing | removeAt() |
Remove at index, returns removed item or null |
| Replacing | replace() |
Replace first match with named params |
| Replacing | upsertWhere() |
Update if found, insert if not |
| Transforming | map() |
Transform all items |
| Transforming | where() |
Keep only matching items (in-place filter) |
| Transforming | sort() |
Sort items with comparator |
| Transforming | swap() |
Swap two items by index |
| Transforming | move() |
Move item from one index to another (drag-and-drop) |
| Querying | contains() |
Check if any item matches |
| Querying | firstWhereOrNull() |
Find first match or null |
| Querying | indexOf() |
Find index of first match |
| Batch | batch() |
Multiple operations → single UI rebuild |
| State | isEmpty / isNotEmpty / length / first / last |
Quick state inspection |
| Listening | onChange() |
Listen with auto-cancel callback |
| Data | setData() |
Replace entire dataset |
| Data | clear() |
Clear items (preserves pagination state) |
| Advanced | modifyState() |
Direct state modification |
New InsertPosition Enum
Replaces the confusing atStart boolean with a self-documenting enum:
// Before (still works, deprecated):
controller.addItem(user, atStart: true);
// After:
controller.add(user, position: InsertPosition.start);
🚫 Deprecated Methods (backward compatible) #
All old helpers now delegate to the new API and show deprecation warnings:
| Old (Deprecated) | New (Recommended) |
|---|---|
listen() |
onChange() |
listenWithCancel() |
onChange() |
updateData() |
setData() |
addItem() |
add() |
addItems() |
addAll() |
updateItemAt() |
update() |
removeWhere() |
remove(where:) |
insertAt() |
insert() |
replaceWhere() |
replace(where:, replacement:) |
mapItems() |
map() |
modifyDirect() |
modifyState() |
🚀 Improvements #
- Return values:
update(),remove(),removeAt(),replace(),swap(),move()return success/count for better control flow. - Named parameters:
remove(where:),replace(where:, replacement:),updateWhere(where:, update:)are self-documenting. - Batch operations:
batch()allows multiple list mutations with a single UI rebuild. - Query helpers:
contains(),firstWhereOrNull(),indexOf()for quick lookups without.items. - Comprehensive docs: Every method includes dartdoc with usage examples.
1.3.0 #
✨ Features #
- Stack Trace Support:
PagyErrornow captures and storesStackTracefor easier debugging. Accessed viaerror.stackTrace. - Flexible Refresh: Added custom refresh indicator support via
refreshIndicatorBuilderand customonRefreshlogic. - Persistence Control: Added
preserveFiltersOnRefresh(global config + per-call) andclearFilters()to manage filter state during refreshes. - Clean Architecture: Optional pathway with
PagyPageRepositoryandGetPaginatedPageUseCase.
🚀 Improvements #
- Filtered State: Filters are now persisted across
loadMore()calls. - Enhanced Logging: Improved debug logging with stacktrace for API and parsing failures.
- Pagination Fallbacks: Added support for
hasMore/totalItemsmetadata andPagyConfig.assumeHasMoreWhenTotalPagesNull. - Payload Reuse:
PagyControllernow reuses initialpayloadDataif per-call payload is omitted. - Smart Formatting: Avoid sending null
page/limitparams; clearerrorMessagewhen error is fixed.
🛠️ Bug Fixes #
- Filter Persistence: Changed
preserveFiltersOnRefreshdefault totrueto ensure pull-to-refresh keeps current filters. - Retry Logic: Fixed
PagyBuilderandPagyControllerLoaderto correctly preserve filters and state during manual retries. - Initialization: Fixed config race conditions where controllers could lock in an unconfigured state.
- Logic: Fixed
loadMore()to always fetch next page correctly. - UI: Relaxed shimmer placeholder requirements when custom
shimmerBuilderis used.
🧪 Testing #
- Added comprehensive unit tests for filter persistence, retry behavior, metadata fallbacks, and stacktrace handling.
1.2.0 #
🎯 Horizontal ListView & Dynamic Height Support #
- ✨ New Widget: Added
PagyHorizontalListView<T>for horizontal scrolling pagination. - 📏 Dynamic Height Support: Added
useDynamicHeightparameter for intrinsic sizing support. - 📐 Column/Flex Layout Ready: Height is automatically determined by content when
useDynamicHeight: true. - 🏗️ Smart Auto-Fallback: Automatically detects unbounded height constraints and switches to dynamic layout - fixes "Horizontal viewport was given unbounded height" errors!
- 🛡️ PagyObserver Enhancements: Added
nullBuilderfor custom null controller handling. - 🔄 Feature Parity: Full support for shimmers, error states, and empty states in horizontal mode.
- 🎨 Customizable Spacing: Easy configuration of
itemSpacingandseparatorBuilder. - ⚠️ Performance Note: Dynamic height builds all items upfront (not lazy) - use with caution for very large lists.
Example Usage #
// Fixed Height (Uses efficient ListView.separated)
SizedBox(
height: 200,
child: PagyHorizontalListView<Category>(
controller: categoryController,
itemBuilderWithIndex: (context, category, index) {
return CategoryCard(category: category);
},
itemSpacing: 12,
),
)
// Dynamic Height (Auto-sized to tallest child - perfect for Columns)
PagyHorizontalListView<Product>(
controller: productController,
useDynamicHeight: true,
itemBuilderWithIndex: (context, product, index) {
return ProductCard(product: product);
},
)
1.1.1 #
🎯 ItemBuilder Enhancement #
- ✨ Index Parameter Support: Added
itemBuilderWithIndexparameter that includes item index access - 🔧 Better Item Builders: Now you can build widgets that need to know their position (e.g., "#1", "#2", etc.)
- 📝 Backward Compatible: Old
itemBuilder(without index) still works but is deprecated - 🔄 Automatic Migration: Use
itemBuilderWithIndex: (context, item, index) => ...instead ofitemBuilder: (context, item) => ...
1.1.0 #
🎯 UX Improvements & New Features #
- 🔄 Refresh on Empty: Added support for pull-to-refresh when the list is empty
- 💬 Empty State Customization: Added
emptyStateBuilder,emptyMessage, andemptyIconfor comprehensive empty state customization - ✨ Built-in Response Parsers: Added
PagyParsersclass with pre-built parsers for common API response structures (Laravel, Django, etc.) - 🏷️ Better Error Handling: Introduced
PagyErrorclass with error types, helpful suggestions, and status codes - 📊 Pagination Metadata: Added
PagyMetadatafor easy access to pagination info in UI (currentPage,totalPages,progress, etc.) - 🔧 Convenience Methods: Added
refresh(),applyFilters(),search(), andloadMore()methods toPagyController - ⚙️ Enhanced Configuration: Added validation for
baseUrl, helpful warnings, and better error messages - 📝 Improved Naming: Introduced clearer parameter names with deprecation strategy:
responseMapper→responseParseradditionalQueryParams→querypaginationMode→payloadMode(controller & config)apiLogs→enableLogs
- 📚 Comprehensive Documentation: Complete README rewrite with examples, migration guide, and common use case
- 🔄 Full Backward Compatibility: All old parameter names still work (deprecated, will be removed in v2.0.0)
1.0.0 #
- 🚀 Remapped the entire package to Clean Architecture for improved scalability and maintainability.
- 📝 Added support for custom headers in API requests.
- 🏗️ Introduced a separate builder option in
PagyListViewfor more flexible UI rendering. - ⏹️ Implemented automatic cancellation of previous API calls when new requests are triggered.
- 🔒 Added interceptor support for advanced request/response handling (e.g., token blacklist).
- 🔗
PagyControllernow integrates seamlessly with both BLoC and Riverpod. - 🧩 Added dependency injection test hooks, removing strict reliance on global
PagyConfig. - 📊 Enhanced logging system to allow monitoring and saving of request/response logs.
- 🌗 Integrated automatic theme support to adapt to the user's app theme (light/dark).
0.0.4 #
- Added POST request support and enhanced API interactions.
- Improved
.gitignore. - Updated dependencies: pagy: ^1.3.0
0.0.3+1 #
- Set Dio compatible version.
0.0.3 #
- Fixed dependency issues.
- Updated compatibility for Flutter 3.32.
- Added functionality to limit the number of displayed items.
0.0.2 #
- Fixed logo.
- Improved example.
0.0.1 #
- Initial release.
- Added assets path.