@@ -7,41 +7,88 @@ import BladeTCA
77import ComposableArchitecture
88import SwiftUI
99
10+ // MARK: - PaginatorListView
11+
1012public struct PaginatorListView <
1113 State: Equatable & Identifiable ,
1214 Action: Equatable ,
15+ Header: View ,
1316 Body: View ,
17+ Footer: View ,
1418 PositionType: Equatable ,
1519 Request: Equatable
1620> : View {
1721 // MARK: Types
1822
1923 private typealias StoreType = ViewStoreOf < PaginatorReducer < State , Action , PositionType , Request > >
2024
25+ @SwiftUI . State private var isLoading = false
26+
2127 // MARK: Properties
2228
2329 public let store : Store < PaginatorState < State , PositionType > , PaginatorAction < State , Action , Request > >
30+ public let header : ( ) -> Header
2431 public let content : ( State ) -> Body
32+ public let footer : ( ) -> Footer
2533
2634 public init (
2735 store: Store < PaginatorState < State , PositionType > , PaginatorAction < State , Action , Request > > ,
28- content: @escaping ( State ) -> Body
36+ @ViewBuilder header: @escaping ( ) -> Header ,
37+ @ViewBuilder content: @escaping ( State ) -> Body ,
38+ @ViewBuilder footer: @escaping ( ) -> Footer
2939 ) {
3040 self . store = store
41+ self . header = header
3142 self . content = content
43+ self . footer = footer
3244 }
3345
3446 // MARK: View
3547
3648 public var body : some View {
37- WithViewStore ( store, observe: { $0 } ) { ( viewStore: StoreType ) in
38- List ( viewStore. items) { item in
39- content ( item)
40- . onAppear {
41- viewStore. send ( . itemAppeared( item. id) )
49+ List {
50+ Section {
51+ header ( )
52+ }
53+
54+ WithViewStore ( store, observe: { $0 } ) { ( viewStore: StoreType ) in
55+ Section ( content: {
56+ ForEach ( viewStore. items) { item in
57+ content ( item)
58+ . onAppear {
59+ viewStore. send ( . itemAppeared( item. id) )
60+ }
4261 }
62+ } )
63+ }
64+
65+ Section {
66+ footer ( )
67+ }
68+
69+ Section {
70+ EmptyView ( )
71+ . modifier ( LoadingViewModifier ( isLoading: isLoading) )
4372 }
44- . modifier ( LoadingViewModifier ( isLoading: viewStore. isLoading && !viewStore. items. isEmpty) )
4573 }
4674 }
4775}
76+
77+ public extension PaginatorListView where Header == EmptyView , Footer == EmptyView {
78+ init (
79+ store: Store < PaginatorState < State , PositionType > , PaginatorAction < State , Action , Request > > ,
80+ @ViewBuilder content: @escaping ( State ) -> Body
81+ ) {
82+ self . init ( store: store, header: { EmptyView ( ) } , content: content, footer: { EmptyView ( ) } )
83+ }
84+ }
85+
86+ public extension PaginatorListView where Header: View , Footer == EmptyView {
87+ init (
88+ store: Store < PaginatorState < State , PositionType > , PaginatorAction < State , Action , Request > > ,
89+ header: @escaping ( ) -> Header ,
90+ @ViewBuilder content: @escaping ( State ) -> Body
91+ ) {
92+ self . init ( store: store, header: header, content: content, footer: { EmptyView ( ) } )
93+ }
94+ }
0 commit comments