@@ -100,7 +100,9 @@ public final class DirectionalNavigationAdapter {
100100 private let pointerPolicy : PointerPolicy
101101 private let keyboardPolicy : KeyboardPolicy
102102 private let animatedTransition : Bool
103+ private let onNavigation : @MainActor ( ) -> Void
103104
105+ @available ( * , deprecated, message: " Use `bind(to:)` instead of notifying the event yourself. See the migration guide. " )
104106 private weak var navigator : VisualNavigator ?
105107
106108 /// Initializes a new `DirectionalNavigationAdapter`.
@@ -110,14 +112,17 @@ public final class DirectionalNavigationAdapter {
110112 /// - keyboardPolicy: Policy on page turns using the keyboard.
111113 /// - animatedTransition: Indicates whether the page turns should be
112114 /// animated.
115+ /// - onNavigation: Callback called when a navigation is triggered.
113116 public init (
114117 pointerPolicy: PointerPolicy = PointerPolicy ( ) ,
115118 keyboardPolicy: KeyboardPolicy = KeyboardPolicy ( ) ,
116- animatedTransition: Bool = false
119+ animatedTransition: Bool = false ,
120+ onNavigation: @escaping @MainActor ( ) -> Void = { }
117121 ) {
118122 self . pointerPolicy = pointerPolicy
119123 self . keyboardPolicy = keyboardPolicy
120124 self . animatedTransition = animatedTransition
125+ self . onNavigation = onNavigation
121126 }
122127
123128 /// Binds the adapter to the given visual navigator.
@@ -162,7 +167,6 @@ public final class DirectionalNavigationAdapter {
162167 }
163168
164169 let bounds = navigator. view. bounds
165- let options = NavigatorGoOptions ( animated: animatedTransition)
166170
167171 if pointerPolicy. edges. contains ( . horizontal) {
168172 let horizontalEdgeSize = pointerPolicy. horizontalEdgeThresholdPercent
@@ -172,9 +176,9 @@ public final class DirectionalNavigationAdapter {
172176 let rightRange = ( bounds. width - horizontalEdgeSize) ... bounds. width
173177
174178 if rightRange. contains ( point. x) {
175- return await navigator . goRight ( options : options )
179+ return await goRight ( in : navigator )
176180 } else if leftRange. contains ( point. x) {
177- return await navigator . goLeft ( options : options )
181+ return await goLeft ( in : navigator )
178182 }
179183 }
180184
@@ -186,9 +190,9 @@ public final class DirectionalNavigationAdapter {
186190 let bottomRange = ( bounds. height - verticalEdgeSize) ... bounds. height
187191
188192 if bottomRange. contains ( point. y) {
189- return await navigator . goForward ( options : options )
193+ return await goForward ( in : navigator )
190194 } else if topRange. contains ( point. y) {
191- return await navigator . goBackward ( options : options )
195+ return await goBackward ( in : navigator )
192196 }
193197 }
194198
@@ -200,24 +204,44 @@ public final class DirectionalNavigationAdapter {
200204 return false
201205 }
202206
203- let options = NavigatorGoOptions ( animated: animatedTransition)
204-
205207 switch event. key {
206208 case . arrowUp where keyboardPolicy. handleArrowKeys:
207- return await navigator . goBackward ( options : options )
209+ return await goBackward ( in : navigator )
208210 case . arrowDown where keyboardPolicy. handleArrowKeys:
209- return await navigator . goForward ( options : options )
211+ return await goForward ( in : navigator )
210212 case . arrowLeft where keyboardPolicy. handleArrowKeys:
211- return await navigator . goLeft ( options : options )
213+ return await goLeft ( in : navigator )
212214 case . arrowRight where keyboardPolicy. handleArrowKeys:
213- return await navigator . goRight ( options : options )
215+ return await goRight ( in : navigator )
214216 case . space where keyboardPolicy. handleSpaceKey:
215- return await navigator . goForward ( options : options )
217+ return await goForward ( in : navigator )
216218 default :
217219 return false
218220 }
219221 }
220222
223+ @MainActor private func goBackward( in navigator: VisualNavigator ) async -> Bool {
224+ await go { await navigator. goBackward ( options: $0) }
225+ }
226+
227+ @MainActor private func goForward( in navigator: VisualNavigator ) async -> Bool {
228+ await go { await navigator. goForward ( options: $0) }
229+ }
230+
231+ @MainActor private func goLeft( in navigator: VisualNavigator ) async -> Bool {
232+ await go { await navigator. goLeft ( options: $0) }
233+ }
234+
235+ @MainActor private func goRight( in navigator: VisualNavigator ) async -> Bool {
236+ await go { await navigator. goRight ( options: $0) }
237+ }
238+
239+ @MainActor private func go( _ action: ( NavigatorGoOptions ) async -> Bool ) async -> Bool {
240+ onNavigation ( )
241+ let options = NavigatorGoOptions ( animated: animatedTransition)
242+ return await action ( options)
243+ }
244+
221245 @available ( * , deprecated, message: " Use the new initializer without the navigator parameter and call `bind(to:)`. See the migration guide. " )
222246 public init (
223247 navigator: VisualNavigator ,
@@ -240,6 +264,7 @@ public final class DirectionalNavigationAdapter {
240264 )
241265 keyboardPolicy = KeyboardPolicy ( )
242266 self . animatedTransition = animatedTransition
267+ onNavigation = { }
243268 }
244269
245270 @available ( * , deprecated, message: " Use `bind(to:)` instead of notifying the event yourself. See the migration guide. " )
0 commit comments