diff --git a/README.md b/README.md index 6a8bc35..68ca9b2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +![Blade: a pagination framework that simplifies the integration of pagination into the application](https://raw.githubusercontent.com/space-code/blade/dev/Resources/blade.png) +

blade

@@ -6,17 +8,21 @@ Platform Compatibility CI CodeCov +
+
Number of GitHub contributors Number of GitHub issues that are open Number of GitHub closed issues Number of GitHub stars Number of GitHub pull requests that are open +
+
GitHub release; latest by date

## Description -`Blade` description. +`Blade` is a pagination framework that simplifies the integration of pagination into the application. - [Usage](#usage) - [Requirements](#requirements) @@ -28,8 +34,133 @@ ## Usage +Blade provides two libraries for working with pagination: `Blade` and `BladeTCA`. `BladeTCA` is an extension designed for working with [Composable Architecture](https://github.com/pointfreeco/swift-composable-architecture). Both support working with offset and cursor-based paginations. + +### Basic Usage + +First, you need to implement page loader for whether cursor or offset based pagination: + +```swift +import Blade + +/// Offset pagination loader + +final class OffsetPageLoader: IOffsetPageLoader { + func loadPage(request: OffsetPaginationRequest) async throws -> Page { + // Implementation here + } +} + +/// Cursor pagination loader + +final class CursorPageLoader: ICursorPageLoader { + func loadPage(request: CursorPaginationRequest) async throws -> Page { + // Implementation here + } +} +``` + +Second, create a `Paginator` instance: + +```swift +import Blade + +/// Offset-based pagination +let paginator = Paginator(configuration: PaginationLimitOffset(firstPage: .zero, limit: 20), offsetPageLoader: OffsetPageLoader()) + +/// Cursor-based pagination +let paginator = Paginator(configuration: PaginationCursorSeek(id: #id_here), offsetPageLoader: CursorPageLoader()) +``` + +Third, the paginator is capable of requesting the first page, the next page, and resetting its state, like this: + +```swift +/// Request an initial page +let page = try await paginator.refresh() + +/// Request next page +let nextPage = try await paginator.nextPage() + +/// Reset state +await paginator.reset() +``` + +### TCA Usage + +If your app uses the [Composable Architecture](https://github.com/pointfreeco/swift-composable-architecture), `Blade` can be easily integrated. + +```swift +import BladeTCA + +// MARK: Reducer + +@Reducer +struct SomeFeature { + // MARK: Types + + struct State: Equatable { + var paginator: PaginatorState + } + + enum Action { + case child(PaginatorAction) + } + + // MARK: Reducer + + var body: some ReducerOf { + Reduce { state, action in + switch state { + case .clild: + return .none + } + } + .paginator( + state: \SomeFeature.State.paginator, + action: /SomeFeature.Action.child, + loadPage: { request, state in + // Load page here + } + ) + } +} + +// MARK: View + +import ComposableArchitecture +import DesignKit +import SwiftUI + +// MARK: - SomeView + +struct SomeView: View { + // MARK: Properties + + private let store: StoreOf + + // MARK: Initialization + + init(store: StoreOf) { + self.store = store + } + + // MARK: View + + var body: some View { + PaginatorListView( + store: store.scope(state: \.paginator, action: { .child($0) }) + ) { state in + // Implement UI here + } + } +``` + ## Requirements +- iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ / watchOS 7.0+ / visionOS 1.0+ +- Xcode 15.0 +- Swift 5.7 + ## Installation ### Swift Package Manager diff --git a/Resources/blade.png b/Resources/blade.png new file mode 100644 index 0000000..8ce176a Binary files /dev/null and b/Resources/blade.png differ