Skip to content

Commit 79e6078

Browse files
committed
feat(events): Add ModalAttemptedToDismiss event
1 parent f8b7e31 commit 79e6078

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

src/index.test.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
ComponentDidAppearEvent,
55
ComponentDidDisappearEvent,
66
CommandCompletedEvent,
7+
ModalAttemptedToDismissEvent,
78
ScreenPoppedEvent,
89
ModalDismissedEvent,
910
BottomTabSelectedEvent,
@@ -19,6 +20,7 @@ import {
1920
useNavigationComponentDidDisappear,
2021
useNavigationCommand,
2122
useNavigationCommandComplete,
23+
useNavigationModalAttemptedToDismiss,
2224
useNavigationModalDismiss,
2325
useNavigationScreenPop,
2426
useNavigationBottomTabSelect,
@@ -431,6 +433,97 @@ describe('useNavigationCommandComplete', () => {
431433
})
432434
})
433435

436+
describe('useNavigationModalAttemptedToDismiss', () => {
437+
let triggerEvent: (event: ModalAttemptedToDismissEvent) => void
438+
let mockRemoveSubscription: () => void
439+
let mockHandler: () => void
440+
441+
beforeEach(() => {
442+
mockHandler = jest.fn(() => {})
443+
mockRemoveSubscription = jest.fn()
444+
445+
Navigation.events = jest.fn().mockReturnValue({
446+
registerModalAttemptedToDismissListener: jest.fn(callback => {
447+
triggerEvent = callback
448+
449+
return { remove: mockRemoveSubscription }
450+
}),
451+
})
452+
})
453+
454+
it('should remove the event listener on unmount', () => {
455+
const { result, unmount } = renderHook(() => {
456+
useNavigationModalAttemptedToDismiss(() => {})
457+
})
458+
459+
unmount()
460+
461+
expect(mockRemoveSubscription).toBeCalledTimes(1)
462+
463+
expect(result.current).toBeUndefined()
464+
expect(result.error).toBeUndefined()
465+
})
466+
467+
it('should never call the handler if no event was triggered', () => {
468+
const { result } = renderHook(() => {
469+
useNavigationModalAttemptedToDismiss(() => {})
470+
})
471+
472+
expect(mockHandler).toBeCalledTimes(0)
473+
474+
expect(result.current).toBeUndefined()
475+
expect(result.error).toBeUndefined()
476+
})
477+
478+
it('should call handler twice when componentId is not provided', () => {
479+
const { result } = renderHook(() => {
480+
useNavigationModalAttemptedToDismiss(mockHandler)
481+
})
482+
483+
const event1 = { componentId: 'COMPONENT_ID_1' }
484+
triggerEvent(event1)
485+
486+
const event2 = { componentId: 'COMPONENT_ID_2' }
487+
triggerEvent(event2)
488+
489+
expect(mockHandler).toBeCalledTimes(2)
490+
expect(mockHandler).toHaveBeenNthCalledWith(1, event1)
491+
expect(mockHandler).toHaveBeenNthCalledWith(2, event2)
492+
493+
expect(result.current).toBeUndefined()
494+
expect(result.error).toBeUndefined()
495+
})
496+
497+
it('should call handler once if componentId provided', () => {
498+
const { result } = renderHook(() => {
499+
useNavigationModalAttemptedToDismiss(mockHandler, 'COMPONENT_ID_1')
500+
})
501+
502+
const event = { componentId: 'COMPONENT_ID_1' }
503+
triggerEvent(event)
504+
505+
expect(mockHandler).toBeCalledTimes(1)
506+
expect(mockHandler).toBeCalledWith(event)
507+
508+
expect(result.current).toBeUndefined()
509+
expect(result.error).toBeUndefined()
510+
})
511+
512+
it('should never call the handler if componentId does not match', () => {
513+
const { result } = renderHook(() => {
514+
useNavigationModalAttemptedToDismiss(mockHandler, 'COMPONENT_ID_1')
515+
})
516+
517+
const event = { componentId: 'COMPONENT_ID_2' }
518+
triggerEvent(event)
519+
520+
expect(mockHandler).toBeCalledTimes(0)
521+
522+
expect(result.current).toBeUndefined()
523+
expect(result.error).toBeUndefined()
524+
})
525+
})
526+
434527
describe('useNavigationScreenPop', () => {
435528
let triggerEvent: (event: ScreenPoppedEvent) => void
436529
let mockRemoveSubscription: () => void

src/index.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
ComponentDidAppearEvent,
55
ComponentDidDisappearEvent,
66
CommandCompletedEvent,
7+
ModalAttemptedToDismissEvent,
78
ModalDismissedEvent,
89
ScreenPoppedEvent,
910
BottomTabSelectedEvent,
@@ -80,6 +81,25 @@ function useNavigationCommandComplete(handler: (event: CommandCompletedEvent) =>
8081
}, [handler, commandName])
8182
}
8283

84+
function useNavigationModalAttemptedToDismiss(
85+
handler: (event: ModalAttemptedToDismissEvent) => void,
86+
componentId?: string
87+
) {
88+
useLayoutEffect(() => {
89+
const subscription = Navigation.events().registerModalAttemptedToDismissListener(event => {
90+
const equalCommandId = event.componentId === componentId
91+
92+
if (componentId && !equalCommandId) {
93+
return
94+
}
95+
96+
handler(event)
97+
})
98+
99+
return () => subscription.remove()
100+
}, [handler, componentId])
101+
}
102+
83103
function useNavigationModalDismiss(handler: (event: ModalDismissedEvent) => void, componentId?: string) {
84104
useLayoutEffect(() => {
85105
const subscription = Navigation.events().registerModalDismissedListener(event => {
@@ -197,6 +217,7 @@ export {
197217
useNavigationComponentDidDisappear,
198218
useNavigationCommand,
199219
useNavigationCommandComplete,
220+
useNavigationModalAttemptedToDismiss,
200221
useNavigationModalDismiss,
201222
useNavigationScreenPop,
202223
useNavigationBottomTabSelect,

0 commit comments

Comments
 (0)